SendMessage() and PostMessage() proper usage - c++

I've got a problem with using SendMessage() and PostMessage() properly. The thing what i'm trying to do is SendMessage(hWnd, WM_USER + 1, 0, 0); in my window procedure
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case WM_CREATE:
break;
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case WM_USER:
break;
case WM_USER + 1:
break;
default:
if (grid.ProcessEvent(wmId, wmEvent))
{
SendMessage(hWnd, WM_USER + 1, 0, 0);
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Im not really sure why it doesn't work, maybe someone could help. I'm sure SendMessage(...) is called but it doesn't affect to run WndProc with my arguments.

The case label case WM_USER + 1: is nested in the inner case statement (that switches on wmId). It needs to be moved out to the switch (message) case statement, so it is at the same level of nesting as case WM_COMMAND: and case WM_DESTROY:.
The above also applies to case WM_USER:.

SendMessage is specified to not return until the receiver window has processed the message - which it cannot do as you're inside your own WndProc and messaging yourself. This is one of those cases where you should be using PostMessage.

Related

Why doesn't drawing onto the hdc immediately update the window?

According to this website, any drawing operation performed on the HDC returned by BeginPaint will immediately display on the screen. However, the number printed by the following code only updates when the window is resized:
int counter = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(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;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
std::string s = std::to_string(counter).c_str();
TextOutA(hdc, 0, 0, s.c_str(), s.length());
EndPaint(hWnd, &ps);
}
break;
case WM_KEYDOWN:
counter++;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Even when continuously sending WM_PAINT to the window with
RedrawWindow(hwndMain, 0, 0, RDW_INTERNALPAINT);
after EndPaint, the number only updates when the window is resized. How can I get the number to update without manually resizing the window?
Calling RedrawWindow with different flags solved the problem.
Specifically RedrawWindow(hWnd, 0, 0, RDW_FRAME | RDW_INVALIDATE); after counter++;

How to display an image in a win32 application?

I'm new to windows in c++ and i can't figure out how to display a image in my window?
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
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;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
//Display an image here.
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
I have a .png file on my desktop with the file path of Desktop\Dirt.png. i want to display this on my window at the location of 0,0. I don't know how to do this so any help will be nice. Also a function for this would be helpful.

get scrollbar id on windows procedure

Here is how I create my scrollbar:
CreateWindowEx(NULL, L"SCROLLBAR", NULL, WS_CHILD | WS_VISIBLE | scrollPos, x, y, width, height, parent, (HMENU)155, GetModuleHandle(NULL), NULL);
How could I restore my id (155) to know which control I will operate?
Here is how I tried:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
int id;
SCROLLBARINFO si;
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (message)
{
case WM_USER:
break;
case WM_USER + 1:
break;
case CONNECT_TO_SERVER:
break;
case WM_VSCROLL:
id = GetDlgCtrlID(hWnd);
//id isn't my 155 id, it is some kind of random number
//wmId isn't my 155 id
break;
case WM_COMMAND:
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
I need to regain this id to choose which one of my controls should react inside my own grid.
id = GetDlgCtrlID(hWnd);
That's not correct, hWnd is the handle to your main window, not the scrollbar control. Also beware that WM_VSCROLL can be sent both by your main window and the scrollbar. The lParam argument tells you where it came from. Fix:
case WM_VSCROLL:
if (lParam != 0) {
int id = GetDlgCtrlID((HWND)lParam);
// etc..
}
break;

C++ Windows Minimize Not Registered

I have added minimize & restore cases to my even processing, but I found out they are never hit.
Only on startup of the program does Size_Minimized get hit. Afterwards, minimize case never happens.
The Size_Restore case never happens either.
Debug stopping at Size_Minimize only on startup of program:
My other cases work, so I have no idea why minimize & restore dont trigger my code or break points.
I conclude that Size_Minimized & Size_Restore are not related to what I need.
What is it I need to know to handle minimize/restore?
Code, in case I did it wrong:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
PAINTSTRUCT ps;
HDC hdc;
switch(message){
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case SIZE_MINIMIZED:
break;
case SIZE_RESTORED:
break;
case WM_SIZING:
case WM_SIZE:
if(engine.isReady()) engine.resizeDevice();
if(engine.isReady()) engine.draw();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
SIZE_MINIMIZED and SIZE_RESTORED are constants passed to you through the WM_SIZE message; they are not window messages. Your breakpoint is getting hit whenever your window receives a window message with the same id as SIZE_MINIMIZED and/or SIZE_RESTORED.
You would need to have your code look something like this:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
PAINTSTRUCT ps;
HDC hdc;
switch(message){
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_SIZE:
switch(wParam) {
case SIZE_MINIMIZED:
// Do whatever
break;
case SIZE_RESTORED:
// Do whatever
break;
}
case WM_SIZING:
if(engine.isReady()) engine.resizeDevice();
if(engine.isReady()) engine.draw();
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

Disable keyboard keys when the console of c Run using c or c++

I want to disable keyboard when my program Run, means that no one can use alt+F4 etc. How I can make it possible using c in window OS.
Handle WM_SYSKEYUP , WM_SYSKEYDOWN and return 0
Here's the WndProc to handle these messages
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
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;
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_KEYDOWN:
case WM_KEYUP:
return 0;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
Pressing alt + f4 sends WM_CLOSE message.
You should properly handled this message.