I'm writing a notepad program and would like the user to be able to press ctrl+n, ctrl+s, ctrl+o, etc, But I'm not even getting a response for the WM_KEYDOWN case. This is how my function is setup:
LRESULT CALLBACK WndProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_CREATE:
// CREATE STUFF HERE
break;
case WM_SIZE:
// RESIZE STUFF HERE
break;
case WM_COMMAND:
// COMMAND ACTIONS HERE
break;
case WM_NOTIFY:
// NOTIFICATIONS HERE
break;
case WM_KEYDOWN:
MessageBox( hwnd, "OK", "OK", MB_OK );
break;
case WM_CLOSE:
// CLOSE WINDOW HERE
break;
case WM_DESTROY:
// DESTROY WINDOW
break;
default:
return DefWindowProc( hwnd, msg, wParam, lParam );
}
return 0;
}
Anybody know what I'm doing wrong? Am I supposed to put the WM_KEYDOWN case somewhere else?
Related
I've been searching for the answer for hours, and a common solution is to respond to a WM_GETDLGCODE message, but I never get that message to respond to.
My example code is:
#include <windows.h>
#include "resource.h"
static LRESULT CALLBACK DlgProc(HWND hDlg, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
switch(uMsg) {
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
switch (wParam) {
case IDOK:
case IDCANCEL:
EndDialog(hDlg, 0);
return TRUE;
}
break;
case WM_GETDLGCODE:
MessageBox(hDlg, "Got WM_GETDLGCODE", "DlgProc", MB_OK);
return DLGC_WANTCHARS;
case WM_CHAR:
MessageBox(hDlg, "Got WM_CHAR", "DlgProc", MB_OK);
break;
}
return FALSE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szcmdline, int iCmdShow)
{
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1),
NULL, DlgProc);
return 0;
}
The dialog is a single edit box (1st tab stop) with the Ok and Cancel buttons. The problem is, I get neither the WM_GETDLGCODE nor the WM_CHAR message. Before I continue down this path, I just want to know if this should work or not. Hooks is my next choice, but if WM_CHAR is available, it seemed like a less complicated solution if I want to keep the dialog modal.
I've created a basic GUI using the windows library and I've come across a problem. The GUI builds and performs great but the issue is the button functions execute before the actual window loads. I wanted the button to execute the desired function on press rather than on load. Below is the code where I think the problem lies.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("T3chSpl01ts Version - 1.0");
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc,
5, 5,
greeting, _tcslen(greeting));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
case WM_CREATE:
{
Button = CreateWindow("Button", "Inject",
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 20, 20, 100, 30,
hWnd, (HMENU)ID_INJECT, GetModuleHandle(NULL), NULL);
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case ID_INJECT:
{
::test();
break;
}
}
}
}
return 0;
}
Your WM_CREATE handler is missing a break statement, so code flow "falls through" into your WM_COMMAND handler when the window is created.
I really do not know what i am doing wrong.
I would like to create a dialogbox.
It is just does not show.
Declaration
BOOL CALLBACK NewDlgProc(HWND main, UINT msg, WPARAM wParam, LPARAM lParam);
Diagproc:
BOOL CALLBACK NewDlgProc(HWND main, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
{
}
break;
default:
return FALSE;
}
return TRUE;
}
In windproc wm_command:
case ID_MENU_NEW:
{
int NewDlg = DialogBox(GetModuleHandle(NULL),
MAKEINTRESOURCE(ID_DIALOG_NEW), main, NewDlgProc);
if(NewDlg == 0)
MessageBox(main, "Cannot create dialogbox", "Error", MB_OK | MB_ICONERROR);
}
break;
resource.h:
#define ID_DIALOG_NEW 201
dlg.rc
#include <windows.h>
#include "resource.h"
ID_DIALOG_NEW DIALOG DISCARDABLE 100,100, 100,100
STYLE DS_MODALFRAME | WS_VISIBLE | WS_CHILD | WS_CAPTION
CAPTION "Add new"
FONT 8, "Ms Sans Serif"
BEGIN
END
A dialog can have an owner or be unowned, but it cannot have a parent. Consequently, you cannot have the WS_CHILD window style for a dialog. Replace that with WS_POPUP, and everyone will be happy.
Relevant quote from the MSDN (About Dialog Boxes : Modal Dialog Boxes):
An application must not create a modal dialog box having the WS_CHILD style.
How come in your dialog procedure you are not calling DefDlgProc() for the messages you are not handling?
BOOL CALLBACK NewDlgProc(HWND main, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
{
}
break;
default:
return DefDlgProc(main, msg, wParam, lParam); // need default processing!!!!!!!!!!
}
return TRUE;
}
I created toplevel window, but for unknown reasons my WNDPROC does not receive WM_LBUTTONDOWN/WM_LBUTTONUP nor WM_MOUSEMOVE messages.
Any suggestions?
Relevant code:
WNDCLASSEX wc = {0};
Wc.cbSize = 48;
Wc.cbWndExtra = 80;
Wc.hCursor = LoadCursorW(g_hInstance, MAKEINTRESOURCEW(1002));
Wc.style = CS_GLOBALCLASS | CS_DBLCLKS;
Wc.lpszClassName = Ici[dItemIndex].sInit;
Wc.lpfnWndProc = Ici[dItemIndex].wInit;
RegisterClassExW(&Wc);
g_hRuler1 = CreateWindowExW(WS_EX_TOOLWINDOW,
RULER_CONTROL,
L"",
WS_POPUP|WS_VISIBLE|0x1,
100 ,100, 40, RECTHEIGHT(g_rScreen),
NULL, NULL, hInst, NULL);
LRESULT WINAPI Ruler_Window(HWND hWindow, UINT uWindow, WPARAM wParam, LPARAM lParam)
{
if (uWindow == WM_GETMINMAXINFO)
{
goto DODEFAULT;
}
if (uWindow == WM_NCCREATE)
{
g_pGRI = RULER_ALLOCATE();
RULER_SET_POINTER(hWindow, (LONG_PTR)g_pGRI);
return 1L;
}
g_pGRI = RULER_GET_POINTER(hWindow);
g_pGRI->hWindow = hWindow;
switch(uWindow)
{
case WM_CREATE:
{
return Ruler_OnCreate(wParam, lParam);
}
case WM_PAINT:
{
return Ruler_OnPaint(wParam, lParam);
}
case WM_MOUSEMOVE:
{
return Ruler_OnMouseMove(wParam, lParam);
}
case WM_DESTROY:
{
return Ruler_OnDestroy(wParam, lParam);
}
case WM_SETCURSOR:
{
return Ruler_OnSetCursor(wParam, lParam);
}
case WM_LBUTTONDOWN:
{
return Ruler_OnLeftButtonDown(wParam, lParam);
}
case WM_LBUTTONUP:
{
return Ruler_OnLeftButtonUp(wParam, lParam);
}
case GM_SETINDICATORS:
{
return Ruler_OnSetIndicators(wParam, lParam);
}
DODEFAULT:
return DefWindowProcW(hWindow, uWindow, wParam, lParam);
}
}
Spy++ messages of window after left button click.
I think that the problem here is that you are most likely not calling DefWindowProc from your custom wndProc method (Ruler_Window).
Your code structure in your wndProc is a little... interesting.
You handle the messages you are interested in in a switch statement (with the exception of WM_NCCREATE, which is fine), but your switch statement doesn't actually have a default: entry... instead you have created a label called DODEFAULT, which you only reference once - when the message is WM_GETMINMAXINFO you goto DODEFAULT. Ignoring the issue of using a goto here, you basically do not handle any messages other than those listed in your code, and more importantly, you don't pass other messages to the default handler.
A very quick, very simple rewrite of your Ruler_Window method:
LRESULT WINAPI Ruler_Window(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_NCCREATE)
{
g_pGRI = RULER_ALLOCATE();
RULER_SET_POINTER(hWindow, (LONG_PTR)g_pGRI);
return DefWindowProcW(hWindow, uMsg, wParam, lParam);
}
// not sure what g_pGRI is, guessing it's a global?
// should this actually be passed into the handlers below?
g_pGRI = RULER_GET_POINTER(hWindow);
g_pGRI->hWindow = hWindow;
switch(uMsg)
{
case WM_CREATE:
return Ruler_OnCreate(wParam, lParam);
case WM_PAINT:
return Ruler_OnPaint(wParam, lParam);
case WM_MOUSEMOVE:
return Ruler_OnMouseMove(wParam, lParam);
case WM_DESTROY:
return Ruler_OnDestroy(wParam, lParam);
case WM_SETCURSOR:
return Ruler_OnSetCursor(wParam, lParam);
case WM_LBUTTONDOWN:
return Ruler_OnLeftButtonDown(wParam, lParam);
case WM_LBUTTONUP:
return Ruler_OnLeftButtonUp(wParam, lParam);
case GM_SETINDICATORS:
return Ruler_OnSetIndicators(wParam, lParam);
default:
break;
}
return DefWindowProcW(hWindow, uMsg, wParam, lParam);
}
Note, I also changed the name of the message parameter to be uMsg, as it makes reading the code much easier, IMHO.
I suspect that the problem is that you are not calling DefWindowProc for WM_NCCREATE and WM_CREATE. This means that the window is never setting up its client areas, so the messages are coming in as WM_NC*.
You should always pass WM_NCCREATE and WM_CREATE on to DefWindowProc.
I have one parent dialog , this dialog have menu , in this menu (Help->about).
when I click on the about selection, show about DialogBox.
I want if I click on Ok or close(X) button, close this dialog box only not the main dialog box.
This my attempts:
// ------------- Main dialog function
BOOL CALLBACK DlgFunc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp){
switch(msg){
case WM_COMMAND:
switch(LOWORD(wp)){
case IDM_HABOUT: // Here, I set when I click on help selection in the menu creates (about dialogbox)
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_AboutDlg), hwnd, AboutDlgFunc);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return false;
}
return true;
}
// ------------- About dialog function
BOOL CALLBACK AboutDlgFunc(HWND HabutWnd, UINT msg, WPARAM wp, LPARAM lp){
switch(msg){
case WM_COMMAND:
if(LOWORD(wp) == IDOK)
EndDialog(HabutWnd,0);
break;
case WM_CLOSE:
EndDialog(HabutWnd,0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return false;
}
return true;
}
Don't call PostQuitMessage in WM_DESTROY inside AboutDlgFunc. This essentially causes the entire program to quit.