Thread: Looking For a GetWindowLongPtr() Type Function (or workaround) for Dialog Boxes

  1. #1
    Registered User
    Join Date
    Jan 2006
    Location
    Seattle
    Posts
    30

    Looking For a GetWindowLongPtr() Type Function (or workaround) for Dialog Boxes

    Hi,

    I’m trying to find a couple functions along the lines of the GetWindowLong(), SetWindowLong() variety except for dialog boxes. It’s my understanding that there’s no HWND created for a dialog box until runtime so I don’t know how to SetWindowLong() without it. For whatever reason I believed that the dialog box’s HWND would inherit the GetWindowLong() that I have set for my main window… nope. I didn’t get any compiler errors (understandable) so when errors started cropping up I started thinking there was a memory leak, after a couple hours I figured out my use of GetWindowLong() was incorrect inside of the dialog box.

    What I’m doing is creating a map maker. I have a class that stores all the information for the map as well as all the functions to manipulate it. The intent for dialog box I’m creating is to change the Width/Height of the map (64x64 pixel tiles). I’ve got the dialog box giving me the correct data upon entry but I can’t change the map without either making the “Info” data global or finding a GetWindowLong() workaround.

    Here’s some code in case I’m doing something stupid, it’s just my callback function for my dialog box. I’m not sure if it’s necessary to show more… I’ve got a lot of code so far and a lot of it is a pretty jumbled mess. It’s my first try taking on something this size by myself.

    Code:
    // Message handler for Height/Width Option box.
    LRESULT CALLBACK Options(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	char height[4];
    	char width[4];
    	WORD sizeOfInput;
    
    	DisplayInfo* Info = (DisplayInfo*)(DWORD_PTR)GetWindowLongPtr(hDlg, GWLP_USERDATA);
    	
    	switch (message)
    	{
    	case WM_INITDIALOG:
    		return TRUE;
    
    	case WM_COMMAND:
    		switch( LOWORD(wParam) )
    		{
    		case IDCANCEL:
    			{
    			EndDialog(hDlg, LOWORD(wParam));
    			return TRUE;
    			}
    		break;
    		case IDOK:
    			{
    			// Getting Height Value
                // Get number of characters. 
                sizeOfInput = (WORD) SendDlgItemMessage(hDlg, 
                                                        IDC_HEIGHT, 
                                                        EM_LINELENGTH, 
                                                        (WPARAM) 0, 
                                                        (LPARAM) 0); 
    
                if (sizeOfInput == 0) 
                { 
                    MessageBox(hDlg, 
                               "No characters entered for Height.", 
                               "Error", 
                               MB_OK); 
    
    				break;
                }
    			else if (sizeOfInput == 1)
    			{
                    MessageBox(hDlg, 
                               "Height must be greater than or equal to 10.", 
                               "Error", 
                               MB_OK); 
    
                    break;
    			}
    
                // Put the number of characters into first word of buffer. 
                *((LPWORD)height) = sizeOfInput; 
    
                // Get the characters. 
                SendDlgItemMessage(hDlg, 
                                   IDC_HEIGHT, 
                                   EM_GETLINE, 
                                   (WPARAM) 0,       // line 0 
                                   (LPARAM) height); 
    
                // Null-terminate the string. 
                height[sizeOfInput] = 0; 
    
    			// Getting Width Value
    			sizeOfInput = (WORD) SendDlgItemMessage(hDlg, 
                                                        IDC_WIDTH, 
                                                        EM_LINELENGTH, 
                                                        (WPARAM) 0, 
                                                        (LPARAM) 0); 
    
                if (sizeOfInput == 0) 
                { 
                    MessageBox(hDlg, 
                               "No characters entered for Width.", 
                               "Error", 
                               MB_OK); 
    
                    break;
                }
    			else if (sizeOfInput == 1)
    			{
                    MessageBox(hDlg, 
                               "Width must be greater than or equal to 10.", 
                               "Error", 
                               MB_OK); 
    
                    break;
    			}
    
                // Put the number of characters into first word of buffer. 
                *((LPWORD)width) = sizeOfInput; 
    
                // Get the characters. 
                SendDlgItemMessage(hDlg, 
                                   IDC_WIDTH, 
                                   EM_GETLINE, 
                                   (WPARAM) 0,       // line 0 
                                   (LPARAM) width); 
    
                // Null-terminate the string. 
                width[sizeOfInput] = 0;
    
    			Info->SetWidthHeight(atoi(height), atoi(width));
    
    			EndDialog(hDlg, TRUE); 
                return TRUE;
    			}
    		}
    	}
    	return FALSE;
    }
    Thanks for any insight anyone can give. I’ve been searching the internet for a while but I have a feeling I’m probably looking for the wrong type of solution.

    -Peter

    PS sorry for the weird formatting of my code, not sure what's going on there. I'm using VS 2005

    *******EDIT*******
    As a side note I just tried my code with "Info" being a global and everything appears to work fine.
    Last edited by Peter5897; 09-06-2006 at 10:32 PM.

  2. #2
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    1. Use DWLP_USER rather than GWLP_USERDATA.
    2. Call DialogBoxParam rather than DialogBox and pass the pointer in the lParam argument.
    3. In WM_INITDIALOG, call SetWindowLongPtr with the lParam value.
    4. Your use of EM_GETLINE will cause a buffer overrun. You need to pass the size of the buffer (minus one to leave room for a nul character), not the number of characters. In your case this would be 3 (sizeof(height) - 1).

  3. #3
    Registered User
    Join Date
    Jan 2006
    Location
    Seattle
    Posts
    30
    Hello again,

    I'm afraid I'm missing something in steps 1-3 (as for 4 my dialog box doesn't have room for more than 3 characters and cuts the user off if they try and enter more but thanks for the help).

    Here's what I've got...
    Code:
    // Message handler for Height/Width Option box.
    LRESULT CALLBACK Options(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	char height[4];
    	char width[4];
    	WORD sizeOfInput;
    
    	DisplayInfo* Info = (DisplayInfo*)(DWORD_PTR)GetWindowLongPtr(hDlg, DWLP_USER);
    	
    	switch (message)
    	{
    	case WM_INITDIALOG:
    			SetWindowLongPtr(hDlg, DWLP_USER, (LONG)(DWORD_PTR)&Info); 
    		return TRUE;
    and where I'm creating the window in my WndProc...

    Code:
    DisplayInfo* Info = (DisplayInfo*)(DWORD_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
    .
    .
    . // bunch of random code which would be out of context
    .
    .
    
    		case ID_EDIT_OPTIONS:
    			DialogBoxParam(hInst, (LPCSTR)IDD_SIZEOPTIONS, hWnd, (DLGPROC)Options, (LPARAM)Info); 
    			//DialogBox(hInst, (LPCSTR)IDD_SIZEOPTIONS, hWnd, (DLGPROC)Options);
    			break;
    Unfortunately I'm still getting the same NULL pointer for Info which probably has to do with me using GetWindowLongPtr() too soon but then I run in to the problem of not knowing how to set it in WM_INITDIALOG. Should I be setting it outside somewhere? Currently it's set to the main window's GWLP_USERDATA.

    Thanks for your help.

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Nearly, try:
    Code:
    SetWindowLongPtr(hDlg, DWLP_USER, lParam);
    Remember, that lParam at this point contains the value you passed as the last argument to DialogBoxParam.

  5. #5
    Registered User
    Join Date
    Jan 2006
    Location
    Seattle
    Posts
    30
    Thank you, you were very helpful, that worked like a charm.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner Needs help in Dev-C++
    By Korrupt Lawz in forum C++ Programming
    Replies: 20
    Last Post: 09-28-2010, 01:17 AM
  2. failure to import external C libraries in C++ project
    By nocturna_gr in forum C++ Programming
    Replies: 3
    Last Post: 12-02-2007, 03:49 PM
  3. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM
  4. Replies: 6
    Last Post: 04-21-2006, 08:49 PM
  5. qt help
    By Unregistered in forum Linux Programming
    Replies: 1
    Last Post: 04-20-2002, 09:51 AM