Thread: automatic button sizing

  1. #1
    Shibby willc0de4food's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    378

    automatic button sizing

    hey... i was wondering if there was a way i could have my program size buttons automatically depending on the text contained within them. reason being i'd like to create a program that can allow the user to add custom buttons depending on if one they want isn't one i create by default. i was also considering having the user create all of the buttons they wanted / needed on their own so that i wouldn't have one there they're never going to use. but in any case - the length of the text contained on a button to me is unknown so it'd just be nice if i could take in the text the user wants displayed on the button, store it in the registry, and then create the button from there of the appropriate size.
    any ideas?
    Registered Linux User #380033. Be counted: http://counter.li.org

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Try something like this:
    Code:
    HWND hwndButton = the button;
    HDC hdc = GetDC(hwndButton);
    SIZE s;
    TCHAR szButtonText[] = _T("The button text"); 
    GetTextExtentPoint32(hdc,szButtonText, _tcslen(szButtonText),&s);
    Then you resize the button so its width is greater than s.cx

  3. #3
    Shibby willc0de4food's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    378
    hMm...interesting. i'll give it a try once i get into coding it.
    mm...its been a while. lol

    ::sigh::
    Registered Linux User #380033. Be counted: http://counter.li.org

  4. #4
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Dont include the resource script. You should have a resource header which you include.

  5. #5
    Shibby willc0de4food's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    378
    what do you mean? i dont have an include for the resource script, but in my resource script i accidently had: #include res.h and yea. that was just a dumb mistake. lol so i dont have it included, i just have it added to my project.
    Registered Linux User #380033. Be counted: http://counter.li.org

  6. #6
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    That's strange... did you edit your post? I remember posting that last comment in regards to someone trying to #include a .rc file, but either I posted my comment in the wrong thread, or you edited your post =/

  7. #7
    Shibby willc0de4food's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    378
    lol i edited my post because i realized my stupidity :]
    Registered Linux User #380033. Be counted: http://counter.li.org

  8. #8
    Shibby willc0de4food's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    378
    kk, so uh...how do i resize the button? lol and did i do things correct?
    Code:
    case IDOK:
                    {
                         int length = GetWindowTextLength(GetDlgItem(hwnd, IDC_TEXT));
                         TCHAR *title;
                         HWND hwndButton = CreateWindowEx(0, TEXT("BUTTON"), TEXT(""), WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
                           ex, why, 80, 20, hwnd, (HMENU)btn, GetModuleHandle(NULL), 0);
                         HDC hdc = GetDC(hwndButton);
                         SIZE s;
                         
                         title = malloc(length + 1);
                         GetDlgItemText(hwnd, IDC_TEXT, title, length);
                         GetTextExtentPoint32(hdc,title, _tcslen(title),&s);
                    }
                    break;
    thanks :]
    Last edited by willc0de4food; 01-04-2006 at 01:50 AM.
    Registered Linux User #380033. Be counted: http://counter.li.org

  9. #9
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    also - which header is tcslen() declared in?
    tchar.h
    If you don't care about making your program unicode compliant, then you can skip that and just use strlen(). If you are sticking with unicode, then change your malloc call to:
    Code:
    title = malloc((length + 1) * sizeof(TCHAR));
    how do i resize the button?
    Use the MoveWindow() function.

  10. #10
    Registered User
    Join Date
    Mar 2004
    Posts
    220
    bithub..how do you know all of this stuff? x.x. Is there some vast archive of knowledge that I'm missing?

    If said vast archive of knowledge is MSDN...well....I guess I just fail at navigating it or something x.x.
    OS: Windows XP Pro CE
    IDE: VS .NET 2002
    Preferred Language: C++.

  11. #11
    Shibby willc0de4food's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    378
    my guess would be he knows it the same way you know how to make a hello world program.
    seeing, reading, practicing :] lol

    but thank you bithub - your help is greatly appreciated.
    works like a champ. now i just have to deal with the button positioning, lol
    Last edited by willc0de4food; 01-04-2006 at 11:56 AM.
    Registered Linux User #380033. Be counted: http://counter.li.org

  12. #12
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    bithub..how do you know all of this stuff? x.x. Is there some vast archive of knowledge that I'm missing?
    I've run into most of the problems posted in this forum at one time or another over the last decade or so. Over time I've gotten better at searching MSDN, and I've built up a code base of about 60 different Windows programs on my hard drive which I can search through when I need to remember how I tackled some problem.

    but thank you bithub - your help is greatly appreciated.

  13. #13
    Shibby willc0de4food's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    378
    k so when the user wants to remove a button from the main window, i open a new dialog. in this new dialog is a select box with the title of each button. from here the user can choose to remove a single item or to clear the entire list. i've got down the removing items from / clearing the list, but how would i go about making it so that when the user removes an item from the list, it will also remove the corresponding button? here's my code for the remove and clear cases:
    Code:
    case IDC_REMOVE:
                    {
                        // When the user clicks the Remove button, we first get the number
    					// of selected items
    
    					HWND hList = GetDlgItem(hwnd, IDC_LIST);
    					int count = SendMessage(hList, LB_GETSELCOUNT, 0, 0);
    					if(count != LB_ERR)
    					{
    						if(count != 0)
    						{
    							// And then allocate room to store the list of selected items.
    
    							int i;
    							int *buf = GlobalAlloc(GPTR, sizeof(int) * count);
    							SendMessage(hList, LB_GETSELITEMS, (WPARAM)count, (LPARAM)buf);
    							
    							// Now we loop through the list and remove each item that was
    							// selected.  
    
    							// WARNING!!!  
    							// We loop backwards, because if we removed items
    							// from top to bottom, it would change the indexes of the other
    							// items!!!
    							if (count == 1)
    							    SetDlgItemText(hwnd, IDC_STATIC, msg1);
    			                else if (count > 1)
    			                    SetDlgItemText(hwnd, IDC_STATIC, msg2);
                                else
                                    MessageBox(NULL, "Error 1000101;\n\nPlease report this error.",
                                      "Error!", MB_OK | MB_ICONEXCLAMATION);
    
    							for(i = count - 1; i >= 0; i--)
    							{
    								SendMessage(hList, LB_DELETESTRING, (WPARAM)buf[i], 0);
    							}
    
    							GlobalFree(buf);
    						}
    						else 
    						{
    							MessageBox(hwnd, "No items selected.", "Warning", MB_OK);
    						}
    					}
    					else
    					{
    						MessageBox(hwnd, "Error counting items :(", "Warning", MB_OK);
    					}
                     }
                    break;
                    case IDC_CLEAR:
                    {
                        // When the user clicks the Clear button, we first select all of the
    					// items and then go ahead just as we did previously with the Remove
                        // button to delete all of the items in the select box. 
                        
    					HWND hList = GetDlgItem(hwnd, IDC_LIST);
    					int count = 0;
    					
    					SendMessage(hList, LB_SETSEL, (WPARAM)TRUE, (LPARAM)-1);
    					count = SendMessage(hList, LB_GETSELCOUNT, 0, 0);
    					
    					if(count != LB_ERR)
    					{
    						if(count != 0)
    						{
    							// And then allocate room to store the list of selected items.
    
    							int i;
    							int *buf = GlobalAlloc(GPTR, sizeof(int) * count);
    							SendMessage(hList, LB_GETSELITEMS, (WPARAM)count, (LPARAM)buf);
    							
    							// Now we loop through the list and remove each item that was
    							// selected.  
    
    							// WARNING!!!  
    							// We loop backwards, because if we removed items
    							// from top to bottom, it would change the indexes of the other
    							// items!!!
    							
    							if (count == 1)
    							    SetDlgItemText(hwnd, IDC_STATIC, msg1);
    			                else if (count > 1)
    			                    SetDlgItemText(hwnd, IDC_STATIC, msg2);
                                else
                                    MessageBox(NULL, "Error 1000101;\n\nPlease report this error.",
                                      "Error!", MB_OK | MB_ICONEXCLAMATION);
    
    							for(i = count - 1; i >= 0; i--)
    							{
    								SendMessage(hList, LB_DELETESTRING, (WPARAM)buf[i], 0);
    							}
    
    							GlobalFree(buf);
    						}
    						else 
    						{
    							MessageBox(hwnd, "There are no items to be removed.", "Warning", MB_OK);
    						}
    					}
    					else
    					{
    						MessageBox(hwnd, "Error counting items :(", "Warning", MB_OK);
    					}
                     }
                    break;
    thanks
    Registered Linux User #380033. Be counted: http://counter.li.org

  14. #14
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    You are making this way harder than it needs to be

    To clear all items from a list:
    Code:
    SendMessage(hwndList,LB_RESETCONTENT,0,0);
    Also, don't use GlobalAlloc() unless you are sure you need to. Just use malloc(). malloc() is faster, and easier to use.

    Here is how I would handle button removal. Each button should have a separate ID. This is the value that gets passed as the HMENU parameter of CreateWindow(). You use this ID to get a handle to the button's HWND, and then you can delete it. The trick is how to get the button ID from a listbox selection.

    When you load the listbox with the button strings, you can also save the button ID. Like this:
    Code:
    int nListboxIndex;
    nListboxIndex = SendMessage(hwndList, LB_ADDSTRING,0,(LPARAM)szButtonString);
    SendMessage(hwndList,LB_SETITEMDATA, nListboxIndex,buttonID);
    Then when a user selects an item from the listbox...
    Code:
    int nSel = the listbox selection;
    int buttonID = SendMessage(hwndList, LB_GETITEMDATA, nSel,0);
    HWND hwndButton = GetDlgItem(hwndDlg,buttonID);

  15. #15
    Shibby willc0de4food's Avatar
    Join Date
    Mar 2005
    Location
    MI
    Posts
    378
    kk. i have a variable that starts where the initially created buttons end. when a button is created, its created with the variable and then after creation the variable has 1 added to it that way they all have an id :] i was thinking ahead.
    thanks for the help. i'll incorporate the thoughts and code you've given me and we can see what happens..
    Registered Linux User #380033. Be counted: http://counter.li.org

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. elliptical button
    By geek@02 in forum Windows Programming
    Replies: 0
    Last Post: 11-21-2006, 02:15 AM
  2. writing text over a deleted button
    By algi in forum Windows Programming
    Replies: 4
    Last Post: 05-02-2005, 11:32 AM
  3. Window won't display on button command!?
    By psychopath in forum Windows Programming
    Replies: 6
    Last Post: 06-22-2004, 08:12 PM
  4. Replies: 1
    Last Post: 05-26-2004, 12:58 AM