How do I disable the 'Close Window' option in the taskbar? - c

How to write a C Code in order to disable the 'Close Window' option in the taskbar?
Compiler: GCC-mingw32
Which API Function should I use?
Thanks.

Make the window's message dispatcher process the message WM_SYSCOMMAND and filter it out if the message's wParam is SC_CLOSE.
Let WndProc be the windows message handler then the code to do might look like this:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
switch (message)
{
case WM_SYSCOMMAND:
if (wParam == SC_CLOSE);
break;
return DefWindowProc(hWnd, message, wParam, lParam);
case ...
}
return 0;
}
This does not remove the "close"-menu item from the application's jump-list (its taskbar's local menu), but disables its functionality.

Related

Menus in WinAPI: Do I use LPARAM or WPARAM for WM_COMMAND?

I've recently started teaching myself WinAPI, so bear with me here.
Compiler: TDM-GCC 4.9.2
OS: Windows 8.1 64-bit
I've recently learned how to create menus using resources. In regards to that, I've noticed something odd about handling the WM_COMMAND message for menus. The MSDN documentation tells me that if I want to handle a message sent from a menu, the command item ID can be found in the low word of WPARAM; so I assumed that the code in my window procedure would look like this:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, LPARAM lParam, WPARAM wParam)
{
switch (msg)
{
case WM_COMMAND:
switch (LOWORD(wParam)) //<--
{
case /*IDs go here*/:
break;
}
break;
//...
}
return 0;
}
However, I noticed that the command items in the menu weren't working. After some debugging, I figured out that wParam was always 0 and my IDs were actually in lParam! I made the quick change to the following code:
switch (lParam)
{
case /*IDs go here*/:
break;
}
And it works!
My question: why?
How come the documentation says it's in wParam when for me it's in lParam?
Also, here are my resource.rc and resource.h files in case it helps:
"resource.h":
#define IDR_MYMENU 101
//These are appearing in LPARAM instead of WPARAM
#define ID_FILE_EXIT 9001
#define ID_STUFF_GO 9002
"resource.rc":
#include "resource.h"
IDR_MYMENU MENU
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", ID_FILE_EXIT
END
POPUP "&Stuff"
BEGIN
MENUITEM "&Go", ID_STUFF_GO
MENUITEM "G&o somewhere else", 0, GRAYED
END
END
Edit 7/23/15:
SOLVED. My window procedure had the wrong signature. Can't believe it was something so trivial! Thanks, cremno!
The WPARAM and LPARAM parameter are not in the correct order in your code:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, LPARAM lParam, WPARAM wParam)
From the WindowProc callback function MSDN documentation:
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
Just swap them to fix your code:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Your WM_COMMAND message handling should check the high-order WORD of wParam first. Because this value tells you if it is a Menu, Accelerator or child control which is sending the message.
swtich(msg)
{
case WM_COMMAND:
{
switch(HIWORD(wParam))
{
case 0: // Menu
{
// Check LOWORD(wParam) here
break;
}
}
return 0;
}
See the table on the MSDN documentation: WM_COMMAND message

Destroying the current window and create a new one

I have a program that is written in WinAPI.
I have the Login Window, and after that, the actual program window.
I want to destroy the login window, and create the new window..
I've been using this :
Destroying the program :
DestroyWindow(MainHwnd);
and the WndProc of the window (of MainHwnd's window):
LRESULT Client::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
break;
case WM_COMMAND:
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(1);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
And the people here in StackOverflow told me in my previous question, that I a'int destroying the window currently, and I'm causing a Stack Overflow which ends where the window is destroyed (the program stills run - so it looks like everything is working as planed), but I do not want to use bad programing (specialy causing stack overflow to destroy a window haha)
So, how can I destroy a window correctly?
Also, some times, when I use DestroyWindow(MainHwnd) it gets inside both WM_DESTROY and WM_CLOSE (in the current WndProc I have posted above).. Is this related to the Stack Overflow problem ?
Btw - I also know how to use Windows Forms in #C, I'm trying to write something like :
this.Close(); which closes the current window (maybe that makes my question more clear)...
Thanks!
From microsoft about the WM_CLOSE:
An application can prompt the user for confirmation, prior to destroying a window, by processing the WM_CLOSE message and calling the DestroyWindow function only if the user confirms the choice. By default, the DefWindowProc function calls the DestroyWindow function to destroy the window.
So calling DestroyWindow(hwnd); or not is the same.
LRESULT Client::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
break;
case WM_COMMAND:
break;
case WM_CLOSE:
//DestroyWindow(hwnd);
break;
or
case WM_CLOSE:
DestroyWindow(hwnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
see an example closing window
Basically is what i said.
valter

Trying Subclassing on Console

I want to trap keyboard messages in a console application, so I tried this:
HWND GetConsoleHwnd(void)
{
#define SIZEBUF 1024
char szBuffer[SIZEBUF];
GetConsoleTitle(szBuffer, SIZEBUF);
#undef SIZEBUF
return FindWindow(NULL, szBuffer);
}
LRESULT CALLBACK ConsoleProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_KEYDOWN:
switch (wParam)
{
//VK Cases
}
break;
}
return CallWindowProc(OldConsoleProc, hwnd, msg, wParam, lParam);
}
this in main:
HWND hwndConsole = GetConsoleHwnd();
OldConsoleProc = (WNDPROC) SetWindowLong(hwndConsole, GWL_WNDPROC,
ConsoleProc);
and this Global Var: WNDPROC OldConsoleProc;
but it doesnt work, what I am doing wrong?
You can't subclass a window of another process this way. You can do it with hooks but I wouldn't recommend trying this on console window. ReadConsoleInput is low-level enough, and it's as far as you can get without ugly nonportable hacks (I'm not even sure there are some events reaching WndProc when the console window is full screen).

Why doesn't SAPI's ISpNotifySource::SetNotifyWindowMessage() send the notification to my WndProc()?

I'm using WinForms, and I'm trying to get SetNotifyWindowMessage() to send a message to the WndProc, but it does not do so.
The function call:
HRESULT initSAPI(HWND hWnd)
{
...
if(FAILED( g_cpRecoCtxt->SetNotifyWindowMessage( hWnd, WM_RECOEVENT, 0, 0 )))
MessageBoxW(hWnd, L"Error sending window message", L"SAPI Initialization Error", 0);
...
}
The WndProc:
LRESULT WndProc (HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
case WM_RECOEVENT:
ProcessRecoEvent(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
Note: initSAPI() is called on a mouse click event.
Have you called ISpRecoContext::SetInterest as well? SetNotifyWindowMessage specifies what to do when an event occurs, but doesn't specify what events to listen for.

How to get virtkey value for WM_KEYDOWN in WS_CHILD?

I want to know the value of virtual key pressed when a child window(like 'edit' or 'button') has focus.
How to do that?
Well one way is to use
WNDPROC g_OldProc;
LRESULT CALLBACK MyEditWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if ( uMsg == WM_KEYDOWN )
{
// Handle key down.
}
return g_OldProc( hwnd, uMsg, wParam, lParam );
}
then at some opportune moment
g_OldProc = (WNDPROC)GetWindowLongPtr( hEdit, GWLP_WNDPROC );
SetWindowLongPtr( hEdit, GWLP_WNDPROC, (LONG_PTR)MyEditWindowProc );
This will replace the window procedure of the hEdit control with your own window procedure that, in turn, calls the original window procedure.
You could catch them at the level of the message loop (before calling DispatchMessage). Nasty but will work.
You could use the GetKeyState Win32 API from within a WM_SETFOCUS handler.

Resources