How To Detect Pushbutton pressing? - winapi

Im trying to build simple application (Using Win32 API) which shows a black window within a button which should close the application, The problem is that I cant figure out how detect a PushBotton click.
Little peace of my code for example:
HWND hButton = CreateWindow(TEXT("Button"),TEXT("Exit"),WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,100,100,50,50,hWnd,0,hInstance,0);

Briefly, you need to give the button an ID and then handle WM_COMMAND messages from that button in your window proc. The article at http://www.infernodevelopment.com/c-win32-api-tutorial gives a decent example.

You need to analyze WM_COMMAND
message in main window procedure:
LRESULT CALLBACK MainWndProc(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam) // second message parameter
{
if ((uMsg == WM_COMMAND) && ((HWND)lParam == hButton)) //check MSDN for WM_COMMAND and BN_CLICKED notifications
{
//button was pressed
}
.......
}

Related

How to detect mouse hovering in a non-client section of a window?

I have a program that paints to the client area about 60hz using Direct3D 9, and the mouse is interfering, so I want to get rid of it only when it moves across the client area.
I thought that calling ShowCursor(false) in WM_MOUSEMOVE and calling ShowCursor(true) when WM_NCMOUSEMOVE is called by the system would work, but it results in a poor behavior.
So I found that TrackMouseEvent() would make the job, but I'm calling it in the following way:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static bool g_fMouseTracking = false;
switch (message)
{
case WM_MOUSEMOVE:
if (!g_fMouseTracking)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = TME_NONCLIENT;
tme.dwHoverTime = HOVER_DEFAULT;
tme.hwndTrack = hWnd;
g_fMouseTracking = TrackMouseEvent(&tme);
}
break;
case WM_NCMOUSEHOVER:
ShowCursor(true);
break;
...
and WM_NCMOUSEHOVER is never called. I don't know why.
Anyway, this is only one piece of code, to do what I want I know I need more code, but if it's not calling WM_NCMOUSEMOVE I can't start doing more advanced mouse hovering tricks.
When you want to track WM_NCMOUSEHOVER you must use TrackMouseEvent in WM_NCMOUSEMOVE.

How can I get a message box to appear every time I left-click in a window?

I want to open a message box with the word "left" when I left click the mouse.
So I used wndproc and MK_LBUTTON, but the wndproc function wrote the code, but the WinMain part doesn't know how to write the code.
I don't want to open a window, but when I searched on Google, I only have a code example that only shows a window.
(Opening the window did not solve the problem ..)
What should I do? Help
(If you've written as much as possible but don't understand the question, please ask me and I'll answer it.
And I'm not good at English, so I wrote a translator.)
my code(try)
#include <windows.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance
, LPSTR lpszCmdParam, int nCmdShow)
{
//???
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
switch (iMessage) {
case MK_LBUTTON:
MessageBox(hWnd, TEXT("left"),TEXT("message"), MB_OK);
}
return(DefWindowProc(hWnd, iMessage, wParam, lParam));
}
MK_LBUTTON is not a message, you need to catch WM_LBUTTONDOWN, WM_LBUTTONUP or WM_LBUTTONDBLCLK.
These messages are only sent to the active window where the mouse is clicked. If you want to catch clicks on all windows then you need to use a mouse hook and pump messages.

SetWindowsHookEx HCBT_CREATEWND GetWindowText

Anyboby knows how to get text of a created window? I set hook on CreateWindow, but GetWindowText returns empty string.
hCBTHook = SetWindowsHookEx(WH_CBT, (HOOKPROC) &CBTHook, g_appInstance, 0);
LRESULT CALLBACK CBTHook(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HCBT_CREATEWND)
{
HWND hwnd = (HWND)wParam;
CHAR buf[256];
GetWindowText(hwnd, buf, 256);
}
return CallNextHookEx(hCBTHook, nCode, wParam, lParam);
}
"The system calls the hook procedure before sending the WM_CREATE or WM_NCCREATE message to the window."
The window may not have text yet, your callback is invoked very early in the process of window creation. The name of the window gets passed in as part of the CREATESTRUCT message sent with WM_CREATE which would be the earliest the window could do something about having text. Even to hard code something, it would have to be in WM_NCCREATE, which still hasn't happened yet when your callback is called.
However, the callback itself also gets passed the the CREATESTRUCT. If the name that was passed to CreateWindow is what you are after, that's available to you as well.

Win32 WH_CBT Hook - close window before it is created

I´m a currently running a global hook that watches for a certain window and then closes it with PostMessage(hWnd,WM_CLOSE,0,0);
The DLL containing the hook:
LRESULT CALLBACK MyFunc(int code, WPARAM wParam, LPARAM lParam)
{
switch(code)
{
case HCBT_CREATEWND:
{
HWND hWnd = (HWND)wParam;
//GetWindowText(hWnd, wintext, 80) returns nothing
//if ( strcmp(wintext, ("Kaspersky Internet Security: license notification")) == 0 )
// {
// Beep(70,100);
// PostMessage(hWnd,WM_CLOSE,0,0);
// }
break;
}
case HCBT_ACTIVATE:
{
HWND hWnd = (HWND)wParam;
GetWindowText(hWnd, wintext, 80);
if ( strcmp(wintext, ("Kaspersky Internet Security: license notification")) == 0 )
{
Beep(70,100);
PostMessage(hWnd,WM_CLOSE,0,0);
}
break;
}
}
...
As you can see i´m using GetWindowText(hWnd, wintext, 80) to determine by window title if the currently activated window is the one to be closed. i´m
closing the window when it is being activated and not when it is created. I would like to close the window when it is being created, that is when HCBT_CREATEWND is true.
The thing is that I can´t use GetWindowText(hWnd, wintext, 80) to get the window title and thereby determine if the window should be closed because when HCBT_CREATEWND is called the window hasn't been fully created and has no title, GetWindowText(hWnd, wintext, 80) returns nothing.
To summarize my question: is it possible to get the title of the window or in any other way determine what kind of window it is, when HCBT_CREATEWND is true?
Could you try GetClassName instead of reading the window text?
It's probably more reliable the reading the window text (internationalization). An easy way to discover a window's class name is to use the spy++ utility - a handy tutorial is described here.
The window isn't created yet. Which means you won't be able to call ::GetWindowText(). Instead use the lParam as an LPCBT_CREATEWND. This gives you access to the CREATESTRUCT via a pointer. You can use the lpszName to get access to the window name.
Something like this --
CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
switch(nCode)
{
case HCBT_CREATEWND:
{
LPCBT_CREATEWND lpCreate = (LPCBT_CREATEWND)lParam;
lpCreate->lpcs->lpszName; // this is the name
break;
}
}
}

How to set the text on the "save" button in Windows' file dialog?

I'm trying to set the text on the "save" button of the Windows "Save file as..." dialog.
I've set up the hook, received the message, found the button (nb. If I call "GetWindowText()" I see "&Save" so I know it's the right button).
Next I changed the text using "SetWindowText()" (and called "GetWindowText()" to check it - the text is correct).
But ... the button still says "Save".
I can change the "Cancel" button using the exact same code - no problem. What's so special about the "Save" button? How can I change it.
Code (for what it's worth):
static UINT_PTR CALLBACK myHook(HWND hwnd, UINT msg, WPARAM, LPARAM)
{
if (msg == WM_INITDIALOG) {
wchar_t temp[100];
HWND h = GetDlgItem(GetParent(hwnd),IDOK);
GetWindowTextW(h,temp,100); // temp=="&Save"
SetWindowTextW(h,L"Testing");
GetWindowTextW(h,temp,100); // temp=="Testing"
}
}
I finally made it work....
I'm pretty sure there's something funny going on with the "Save" button but this code will wrestle it into submission:
// I replace the dialog's WindowProc with this
static WNDPROC oldProc = NULL;
static BOOL CALLBACK buttonSetter(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Set the button text on every window redraw....
if (msg == WM_ERASEBKGND) {
SetDlgItemTextW(hwnd,IDOK,L"OK");
}
return oldProc(hwnd, msg, wParam, lParam);
};
// This is the callback for the GetWriteName hook
static UINT_PTR CALLBACK GWNcallback(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
HWND dlg = GetParent(hwnd);
if (msg == WM_INITDIALOG) {
oldProc = (WNDPROC)GetWindowLongPtr(dlg, GWL_WNDPROC);
if (oldProc !=0) {
SetWindowLongPtr(dlg, GWL_WNDPROC, (LONG)buttonSetter);
}
}
// We need extra redraws to make our text appear...
InvalidateRect(dlg,0,1);
}
You probably need to redraw the window after setting the text.
Try calling UpdateWindow() after setting the text.
Use CDM_SETCONTROLTEXT message to set the text rather than mess with SetWindowText directly, i.e.
SendMessage(hwnd, CDM_SETCONTROLTEXT, IDOK, L"Testing");
http://msdn.microsoft.com/en-us/library/ms646960(VS.85).aspx has more on customizing open/save dialogs

Resources