[C++/Win32] - Having trouble understanding how controls work with messages

Started by
3 comments, last by Khatharr 13 years, 6 months ago
Here's my code:

#include <windows.h>#include <commctrl.h>#include <stdio.h>#define IDC_SLIDER1 101#define IDC_PROGRESS1 102 #define IDC_BUTTON1 103const char g_szClassName[] = "myWindowClass";LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);HFONT hfont0;HWND hCtrl0_0, hCtrl0_1, hCtrl0_2;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {  //create and register window class  WNDCLASSEX wc;  ZeroMemory(&wc, sizeof(wc));  wc.cbSize = sizeof(wc);  wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);  wc.lpszMenuName = NULL;  wc.style = CS_HREDRAW|CS_VREDRAW;  wc.lpfnWndProc = WndProc;  wc.hInstance = hInstance;  wc.hIcon = LoadIcon(0, (LPCTSTR)IDI_APPLICATION);  wc.hCursor = LoadCursor(NULL, IDC_ARROW);  wc.lpszClassName = g_szClassName;  if(!RegisterClassEx(&wc)) {MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0;}  //populate window with controls  hfont0 = CreateFont(-11, 0, 0, 0, 400, FALSE, FALSE, FALSE, 0, 400, 2, 1, 1, ("Microsoft Sans Serif"));  HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW, g_szClassName, "Controls Test", WS_OVERLAPPEDWINDOW, 200, 200, 306, 123, 0, 0, hInstance, 0);  hCtrl0_0 = CreateWindowEx(0, TRACKBAR_CLASS, 0, WS_VISIBLE | WS_CHILD | WS_TABSTOP | TBS_BOTH | TBS_NOTICKS, 3, 36, 294, 26, hwnd, (HMENU)IDC_SLIDER1, hInstance, 0);  SendMessage(hCtrl0_0, WM_SETFONT, (WPARAM)hfont0, FALSE);  SendMessage(hCtrl0_0, TBM_SETRANGE, FALSE, MAKELONG(1, 100));  SendMessage(hCtrl0_0, TBM_SETPOS, FALSE, 1);  hCtrl0_1 = CreateWindowEx(0, PROGRESS_CLASS, 0, WS_VISIBLE | WS_CHILD, 3, 5, 294, 20, hwnd, (HMENU)IDC_PROGRESS1, hInstance, 0);  SendMessage(hCtrl0_1, WM_SETFONT, (WPARAM)hfont0, FALSE);  SendMessage(hCtrl0_0, PBM_SETRANGE, FALSE, MAKELONG(1, 100));  hCtrl0_2 = CreateWindowEx(0, WC_BUTTON, ("OK"), WS_VISIBLE | WS_CHILD | WS_TABSTOP | 0x00000001, 105, 68, 90, 23, hwnd, (HMENU)IDC_BUTTON1, hInstance, 0);  SendMessage(hCtrl0_2, WM_SETFONT, (WPARAM)hfont0, FALSE);  //start 'er up and run the control loop  ShowWindow(hwnd, nCmdShow);  UpdateWindow(hwnd);  MSG Msg;  while(GetMessage(&Msg, NULL, 0, 0) > 0) {    TranslateMessage(&Msg);     DispatchMessage(&Msg);  }  return Msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {  unsigned int pos;  switch(msg) {    case BN_CLICKED: break; //this never gets triggered for some reason    case TB_ENDTRACK: //this isn't working correctly      pos = SendMessage(hCtrl0_0, TBM_GETPOS, NULL, NULL);      SendMessage(hCtrl0_1, PBM_SETPOS, pos, NULL);      break;    case WM_CLOSE: DestroyWindow(hwnd); break;    case WM_DESTROY: PostQuitMessage(0); break;    default: return DefWindowProc(hwnd, msg, wParam, lParam);  }  return 0;}


I'm running into some problems. What I want it to do is set the progress bar according to the value of the slider and quit the app when the OK button is pressed. I've tried using TB_THUMBTRACK rather than TB_ENDTRACK but that doesn't seem to work either. The progress bar only seems to set itself when I first touch the slider and then stops responding. The BN_CLICKED message never gets recieved by the proc.

When I looked over the definitions for the messages I saw that a lot of controls could potentially send the same message, so I'm pretty sure I'm missing something here. Can anyone tell me why this isn't working and what I'm missing here???

Thanks in advance for any advice. :)
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
Advertisement
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {  unsigned int pos;  switch(msg) {  case WM_COMMAND:	  switch(wParam)	  {		//Do control stuff here!	  }	  break;    case WM_CLOSE: 		DestroyWindow(hwnd); 		break;    case WM_DESTROY: 		PostQuitMessage(0); 		break;    default: 		return DefWindowProc(hwnd, msg, wParam, lParam);  }  return 0;}


However, I'm not sure how to handle those BN_ and TB_ messages. But you MUST put them into the switch(WM_COMMAND).

WM_COMMAND gets sent when a controls wants something from you.
I'll check out WM_COMMAND on MSDN and see if it explains where to put the message type.

---------------------------------------

Looks like HIWORD(wParam) is the message sent from the control and LOWORD(wParam) is the id number of the control. I've got the button working now, and the this seems better conceptually but the slider still isn't doing what I want. I'll fiddle with it a little more. Thank you again!

[Edited by - Khatharr on September 25, 2010 10:28:23 PM]
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.
A slider (track bar) sends its notification messages via either WM_HSCROLL or WM_VSCROLL. Look those messages up in MSDN and you'll get nice sample code.

And, even more important: MOVE THE CALL TO DEFWINDOWPROC AFTER THE SWITCH, NOT AS DEFAULT CASE. For most messages you want to pass the messages on to get handled properly.

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>

Okay, I've got it working now. Still one or two things with the trackbar that seem needlessly complex so I didn't go into them, but I learned what I was looking for and I know where the other info can be found.

Thanks for the help, you guys. And yeah, I restructured my proc when I started walking through it in my head. I tried it with WM_HSCROLL but it was producing strange results that would end up making the bar reset to zero whenever I wasn't moving it, so I went with WM_NOTIFY. Apparently a trackbar will send a notification message whenever its value is being changed, so I just set it up so that whenever a notification is recieved from the trackbar it updates the progress bar with the current trackbar position.

Here's the code I ended up with. Nothing exciting, but still:
#include <windows.h>#include <commctrl.h>#define IDC_SLIDER1 101#define IDC_PROGRESS1 102 #define IDC_BUTTON1 103const char g_szClassName[] = "myWindowClass";LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);HFONT hfont0;HWND hCtrl0_0, hCtrl0_1, hCtrl0_2;int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {  //create and register window class  WNDCLASSEX wc;  ZeroMemory(&wc, sizeof(wc));  wc.cbSize = sizeof(wc);  wc.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);  wc.lpszMenuName = NULL;  wc.style = CS_HREDRAW|CS_VREDRAW;  wc.lpfnWndProc = WndProc;  wc.hInstance = hInstance;  wc.hIcon = LoadIcon(0, (LPCTSTR)IDI_APPLICATION);  wc.hCursor = LoadCursor(NULL, IDC_ARROW);  wc.lpszClassName = g_szClassName;  if(!RegisterClassEx(&wc)) {MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0;}  //populate window with controls  hfont0 = CreateFont(-11, 0, 0, 0, 400, FALSE, FALSE, FALSE, 0, 400, 2, 1, 1, ("Microsoft Sans Serif"));  HWND hwnd = CreateWindowEx(WS_EX_APPWINDOW, g_szClassName, "Controls Test", WS_OVERLAPPEDWINDOW, 200, 200, 306, 123, 0, 0, hInstance, 0);  hCtrl0_0 = CreateWindowEx(0, TRACKBAR_CLASS, 0, WS_VISIBLE|WS_CHILD|WS_TABSTOP|TBS_BOTH|TBS_NOTICKS, 3, 36, 294, 26, hwnd, (HMENU)IDC_SLIDER1, hInstance, 0);  SendMessage(hCtrl0_0, WM_SETFONT, (WPARAM)hfont0, FALSE);  SendMessage(hCtrl0_0, TBM_SETRANGE, FALSE, MAKELONG(0, 100));  SendMessage(hCtrl0_0, TBM_SETPOS, FALSE, 0);  hCtrl0_1 = CreateWindowEx(0, PROGRESS_CLASS, 0, WS_VISIBLE|WS_CHILD|PBS_SMOOTH, 3, 5, 294, 20, hwnd, (HMENU)IDC_PROGRESS1, hInstance, 0);  SendMessage(hCtrl0_1, WM_SETFONT, (WPARAM)hfont0, FALSE);  SendMessage(hCtrl0_0, PBM_SETRANGE, FALSE, MAKELONG(0, 100));  hCtrl0_2 = CreateWindowEx(0, WC_BUTTON, ("OK"), WS_VISIBLE|WS_CHILD|WS_TABSTOP|0x00000001, 105, 68, 90, 23, hwnd, (HMENU)IDC_BUTTON1, hInstance, 0);  SendMessage(hCtrl0_2, WM_SETFONT, (WPARAM)hfont0, FALSE);  //start 'er up and run the control loop  ShowWindow(hwnd, nCmdShow);  UpdateWindow(hwnd);  MSG Msg;  while(GetMessage(&Msg, NULL, 0, 0) > 0) {    TranslateMessage(&Msg);     DispatchMessage(&Msg);  }  return Msg.wParam;}LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {  unsigned pos;  switch(msg) {    case WM_NOTIFY:      if(wParam == IDC_SLIDER1) {        pos = SendMessage(hCtrl0_0, TBM_GETPOS, NULL, NULL);        SendMessage(hCtrl0_1, PBM_SETPOS, pos, NULL);        return 1;      }      return DefWindowProc(hwnd, msg, wParam, lParam);    case WM_COMMAND:      if((LOWORD(wParam) == IDC_BUTTON1) && (HIWORD(wParam) == BN_CLICKED)) {        PostQuitMessage(0);        return 1;      }      return DefWindowProc(hwnd, msg, wParam, lParam);    case WM_CLOSE:      DestroyWindow(hwnd);      break;    case WM_DESTROY:      PostQuitMessage(0);      break;  }  return DefWindowProc(hwnd, msg, wParam, lParam);}
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

This topic is closed to new replies.

Advertisement