Click to See Complete Forum and Search --> : problem with SetWindowLong(hwnd,0,0) and GetWindowLong(hwnd,0)


Stern_Pea
May 3rd, 2003, 08:22 AM
Hi everybody :D :

I saw this two functions on a book

and then looked up in MSDN.
like this:
LONG SetWindowLong(
HWND hWnd,
int nIndex,
LONG dwNewLong
);

but I still don't understand the funtion of :

SetWindowLong(hwnd,0,0) ;//on/off flag ?

SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0));

GetWindowLong (hwnd, 0));

why using the these paramaters and when to use them.

only use a buffer to set flag? user define it or windows define it?

Thank you

///////////////////////////////////////////

attach part of the code

LRESULT CALLBACK ChildWndProc (HWND hwnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
HDC hdc ;
PAINTSTRUCT ps ;
RECT rect ;

switch (message)
{
case WM_CREATE :
SetWindowLong (hwnd, 0, 0) ; // on/off flag
return 0 ;

case WM_KEYDOWN:
// Send most key presses to the parent window

if (wParam != VK_RETURN && wParam != VK_SPACE)
{
SendMessage (GetParent (hwnd), message, wParam, lParam) ;
return 0 ;
}
// For Return and Space, fall through to toggle the square

case WM_LBUTTONDOWN :
SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;
SetFocus (hwnd) ;
InvalidateRect (hwnd, NULL, FALSE) ;
return 0 ;

// For focus messages, invalidate the window for repaint

case WM_SETFOCUS:
idFocus = GetWindowLong (hwnd, GWL_ID) ;

// Fall through

case WM_KILLFOCUS:
InvalidateRect (hwnd, NULL, TRUE) ;
return 0 ;

case WM_PAINT :
hdc = BeginPaint (hwnd, &ps) ;

GetClientRect (hwnd, &rect) ;
Rectangle (hdc, 0, 0, rect.right, rect.bottom) ;

// Draw the "x" mark

if (GetWindowLong (hwnd, 0))
{
MoveToEx (hdc, 0, 0, NULL) ;
LineTo (hdc, rect.right, rect.bottom) ;
MoveToEx (hdc, 0, rect.bottom, NULL) ;
LineTo (hdc, rect.right, 0) ;
}
// Draw the "focus" rectangle

if (hwnd == GetFocus ())
{
rect.left += rect.right / 10 ;
rect.right -= rect.left ;
rect.top += rect.bottom / 10 ;
rect.bottom -= rect.top ;

SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
SelectObject (hdc, CreatePen (PS_DASH, 0, 0)) ;
Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ;
DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;
}

EndPaint (hwnd, &ps) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}

Stern_Pea
May 4th, 2003, 09:53 AM
it really puzzle me :confused:

forgive my poor English..

but no one can help me ?

yours sencerely Pea

poccil
May 4th, 2003, 10:43 AM
The code you posted implements a simple checkbox control.

GetWindowLong and SetWindowLong access the window's memory. In this particular application, a bit in the window's memory is toggled according to whether the user has clicked on the checkbox to show the X.

Stern_Pea
May 4th, 2003, 11:11 AM
Originally posted by poccil
The code you posted implements a simple checkbox control.

GetWindowLong and SetWindowLong access the window's memory. In this particular application, a bit in the window's memory is toggled according to whether the user has clicked on the checkbox to show the X.

:D Yes ,, But why the Index parameter in SetWindowLong is '0' ?
Is '4' or '8' and so on OK?
Just find a 4 byte memery to store the flag?
is that will conflict with the data store in previous memery ?

the return value of GetWindowLong describes in MSDN:
If the function succeeds, the return value is the previous value of the specified 32-bit integer.

waiting for your help.

rxbagain
May 4th, 2003, 08:09 PM
SetWindowLong index of 0 is defined as DWL_MSGRESULT. WindowLong indexes to store data, modify it's style, behavior and so other characteristics regarding that specific window.

The indexes is defined in MSDN. You cannot just define any number as index because the system validates if the index u placed is withing the allowed indexes set.

You cannot also just use any indexes to store your data. For example, if you use the GWL_WNDPROC or DWL_DLGPROC index to store you check bit in it, It will surely crash your program because GWL_WNDPROC or DWL_DLGPROC is used to set the WindProc of that window.

The most common used indexes to store user defined data are DWL_USER and GWL_USERDATA

Hope this will help you

Stern_Pea
May 4th, 2003, 11:33 PM
Thank rxbagain :


But sill a little problem .. You see the
#define DWL_MSGRESULT 0
is define for dialog box... But the hwnd parameter for SetWindowLong in that code is a Child window's handle ... Is that not call any problem ?

While define the window class in this programe :
wndclass.lpfnWndProc = ChildWndProc ;
wndclass.cbWndExtra = sizeof (long) ;
wndclass.hIcon = NULL ;
wndclass.lpszClassName = szChildClass ;


In MSDN:

The following values are also available when the hWnd parameter identifies a dialog box.
DWL_DLGPROC
Sets the new address of the dialog box procedure.
DWL_MSGRESULT
Sets the return value of a message processed in the dialog box procedure.
DWL_USER
Sets new extra information that is private to the application, such as handles or pointers.


I search the define Index in Winuser.h and the result like this:

/*
* Window field offsets for GetWindowLong()
*/
#define GWL_WNDPROC (-4)
#define GWL_HINSTANCE (-6)
#define GWL_HWNDPARENT (-8)
#define GWL_STYLE (-16)
#define GWL_EXSTYLE (-20)
#define GWL_USERDATA (-21)
#define GWL_ID (-12)

/*
* Get/SetWindowWord/Long offsets for use with WC_DIALOG windows
*/
#define DWL_MSGRESULT 0
#define DWL_DLGPROC 4
#define DWL_USER 8

rxbagain
May 5th, 2003, 12:00 AM
The code wndclass.cbWndExtra = sizeof (long) ; allocates a 4 bytes of data for your window. This is what a dialog is doing to store the 3 DWL_XXXXXX.

So by placing a space of 4, we can use the index 0 (DWL_DWL_MSGRESULT) to store our data.

We can also use it without any trouble because our window does not use it (because it's not a real dialog), and we can explicitly do whatever we want to do with this window memory space

Hope this will help you

Stern_Pea
May 5th, 2003, 02:46 AM
Oh,,, Thank you very much ..
Now I've understood sth..
I've just reading programming windows for 200 pages and have little experience in windows programming.

In MSDN :
Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASSEX structure used with the RegisterClassEx function.