Newbie needs help

So I made a button. Yay! This is what it looks like :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
...
...
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

#define BUTTON_ID      1001
HDC hdc;
static HWND Button1;
...
...

switch (message)
	{
	case WM_CREATE:
                Button1 = CreateWindow( L"button", L"News Box",
                          WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
                          50, 100, 
                          100, 40,
                          hWnd, (HMENU) BUTTON_ID,
                          hInst, NULL );
        break;
...
...


My question : How does the program know if the button is pushed, and how can I use that in code? (I know the button must have a value like null/int depending on its state, but how do I check this variable, and use it in code?

I'm assuming it's something like - Example :
1
2
3
4
if (somefunctiontogetbuttonvalue(1001)==1){
 //Then run this code
}


can anyone help?
Buttons have a position. A cursor has a position. When mouse button 1 is pressed, check position of mouse to see if it is on this button. If so, your button is pressed.
^

That's a hack, not a solution.
Uh that's not a hack. That's how it's done. Just most libraries hide all that from you.
maybe so, but I'd still like to know the inner workings of the api rather than work around them.
Last edited on
I literally just told you how to do this. What else are you asking?
Well, I just went and learned about case: WM_LBUTTONDOWN, but it's not working on buttons... it works everywhere but my buttons.
Last edited on
The WM_LBUTTONDOWN message is sent to the button window. It then sends its parent a WM_COMMAND message.

So your main window's WndProc needs to handle WM_COMMAND looking for an ID value of BUTTON_ID (the ID is the low word of wParam, the high word the notifcation code, which will be BN_CLICK.) As follows:

(Here the IDs are for menu items. All basic controls (like Button, ComboBox, and ListBox), menu items, and accelerators are handled via the WM_COMMAND message. The only difference being that neither menu items nor accelerators use notification codes. But the newer controls in COMCTL32.DLL (like the List View, Rebar, and Tab) use a different message: WM_NOTIFY.)

Where

int wmId, wmEvent;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// Parse the menu selections:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;


Andy

WM_COMMAND message
http://msdn.microsoft.com/en-us/library/windows/desktop/ms647591%28v=vs.85%29.aspx

BN_CLICKED notification code
http://msdn.microsoft.com/en-us/library/windows/desktop/bb761825%28v=vs.85%29.aspx
Last edited on
The WM_LBUTTONDOWN message is sent to the button windows. It will then send its parent a WM_COMMAND message.


This I understand.

So you main window's WndProc needs to handle WM_COMMAND

You mean make a case WM_COMMAND: {}?

looking for an ID value of BUTTON_ID

Kinda lost here. By looking for ID value of BUTTON_ID, wouldn't that be 1001 as stated in
#define BUTTON_ID 1001 on line 6?

the high word the notifcation code, which will be BN_CLICK

And totally lost here.

I'm confused, when I look up BN_CLICK, it seems to me that the l/w params alone are enough to tell if I clicked inside the "button window" that I created. So is WM_LBUTTONDOWN really necessary?

Also, I have no idea what a notification code is.

You mean make a case WM_COMMAND:

Yes.

By looking for ID value of BUTTON_ID, wouldn't that be 1001 as stated in ...

Yes.

You should use BUTTON_ID, but it would work equally well (if less readably) if you used 1001 instead.

So is WM_LBUTTONDOWN really necessary?

As far as the button click goes, your main window does not need to handle it.

If you need to respond to a button clicks elsewhere, that's another matter.

But it is necessary in the sense that the button has to be sent it, and handle it.

I have no idea what a notification code is.

It's just another ID. But this time it identifies what's happened, rather than what control it happened to (which is the point of the control ID.)

For notification codes for Button controls included (see the Windows SDK header winuser.h for more of the same.)

1
2
3
4
5
6
#define BN_CLICKED          0
#define BN_PAINT            1
#define BN_HILITE           2
#define BN_UNHILITE         3
#define BN_DISABLE          4
#define BN_DOUBLECLICKED    5 


Andy
Last edited on
Okay I think I understand now.

What I did was make something like this :

1
2
3
4
5
6
7
8
9
10
11
..
..
case WM_COMMAND:
        switch(wmId)
        {
         ...
             case BUTTON_ID:
                    //code for button
                    break;
..
..


I also understand that under the circumstances of multiple buttons I can use additional case/if else statements to control what button does what.

This is precisely what I was looking for, thank you for helping me understand.
I have no idea what a notification code is.

While searching for in formation on a different matter. I bumped into this article from Raymond Chen's log "The Old New Thing" (a very worthwhile read if you're a Windows programmer!)

Restating the obvious about the WM_COMMAND message
http://blogs.msdn.com/b/oldnewthing/archive/2006/03/02/542115.aspx

The entry mentions notification codes.

Andy
Last edited on
Topic archived. No new replies allowed.