Can anyone provide an example of how to use windows ShutdownBlockReasonCreate - c++

Can anyone provide a simple clear example of ShutdownBlockReasonCreate? I've been trying to figure it out through the MSDN pages but I'm not understanding it, and I'm getting really tired of having to turn off my computer every time I try and test it and it doesn't work. If someone is familiar and can provide a concise example that would be awesome!
This is what I have so far, but I do'
#include <Windows.h>
#include <iostream>
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
int main(int argc, char* argv[])
{
if (ShutdownBlockReasonCreate(GetForegroundWindow(), s2ws("TEST").c_str()) != 0)
std::cout << "Success" << std::endl;
else
std::cout << "Failure" << std::endl;
while (1)
{
Sleep(1000);
std::cout << "Testing..." << std::endl;
}
}

This works for me in Windows 7. You could also do it in a console program if you liked, this was a simpler example to write. You should add error checking, I didn't to keep it short.
#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
HINSTANCE hInst;
HWND hWnd;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(message)
{
case WM_QUERYENDSESSION:
return FALSE;
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_CREATE:
ShutdownBlockReasonCreate(hWnd, L"Don't do it!");
break;
case WM_DESTROY:
ShutdownBlockReasonDestroy(hWnd);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"TestClass";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
RECT sz = {0, 0, 512, 512};
AdjustWindowRect(&sz, WS_OVERLAPPEDWINDOW, TRUE);
hWnd = CreateWindow(L"TestClass", L"Test Window", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, sz.right - sz.left, sz.bottom - sz.top,
NULL, NULL, hInstance, NULL);
if(!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
MyRegisterClass(hInstance);
if(!InitInstance(hInstance, nCmdShow))
{
return FALSE;
}
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
A console version doesn't need to be drastically different, although you do need to create a window and run a message pump so I'm not sure what it buys you over a GUI app. Obviously if you want to do work in either version you'll most likely end up needing a separate thread for the window or for your work.
Here's the simplest example of a console program I came up with. You'll notice it's almost identical other than the ConsoleCtrlHandler to intercept the various ways of closing the console window and killing the GUI window instead. It's also expected to be a MBCS project since I didn't want to change it in my test console project.
#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
HINSTANCE hInst;
HWND hWnd;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(message)
{
case WM_QUERYENDSESSION:
return FALSE;
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_CREATE:
ShutdownBlockReasonCreate(hWnd, L"Don't do it!");
break;
case WM_DESTROY:
ShutdownBlockReasonDestroy(hWnd);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "TestClass";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
RECT sz = {0, 0, 512, 512};
AdjustWindowRect(&sz, WS_OVERLAPPEDWINDOW, TRUE);
hWnd = CreateWindow("TestClass", "Test Window", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, sz.right - sz.left, sz.bottom - sz.top,
NULL, NULL, hInstance, NULL);
if(!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType)
{
if(dwCtrlType == CTRL_C_EVENT ||
dwCtrlType == CTRL_BREAK_EVENT ||
dwCtrlType == CTRL_CLOSE_EVENT)
{
SendMessage(hWnd, WM_CLOSE, 0, 0);
return TRUE;
}
return FALSE;
}
int main()
{
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
HINSTANCE hInstance = GetModuleHandle(NULL);
MyRegisterClass(hInstance);
if(!InitInstance(hInstance, SW_HIDE))
{
return FALSE;
}
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}

As you can probably guess by now, ShutdownBlockReasonCreate() does not actually block shutdown. All it does is tell Windows what message to say when it pops up this screen.
To block shutdown on Windows, you need to have a window. This means that you will need to write a GUI program that uses a standard message pump. WM_QUERYENDSESSION is a message that is sent to all windows when the system wants to shut down. You can handle the message to block the shutdown request. But to understand this, you will need to understand Windows GUI programming. (You might not need an actual GUI; a message-only window might work. I don't know for sure.)
Your first question on the matter was about blocking shutdown from a system service. I am not an expert on Windows services so I don't know the answer to that. Services should not have GUIs due to running on session 0, however. I don't know if they can have message-only windows either.

Related

Message Box is not working inside WM_COMMAND! (WIN32 API)

I am new to Win32 API and trying to learn it. I was successful to create a window and it works perfectly.
I added a button to it and want to show a message box when clicked. The button works perfectly but the message box in WM_COMMAND does not appear at all and the code below message box does not get executed as well.
I have checked online for how to do it and it seems to work for them but not me.
Here is the code
#include <Windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
WNDCLASSEX wcex;
static TCHAR szWindowClass[] = _T("DesktopApp");
static TCHAR szTitle[] = _T("First Application");
HINSTANCE hInst;
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int CALLBACK WinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPSTR lpCmdLine,_In_ int nCmdShow)
{
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL, _T("Call to Register Failed"), _T("Windows Desktop Guided Tour"), NULL);
return 1;
}
hInst = hInstance;
HWND hwnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, hInstance, NULL);
if (!hwnd)
{
MessageBox(NULL, _T("Failed to create a window"), _T("Windows Desktop Guided Tour"), NULL);
return 1;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
HWND button;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello world! This is the first ever application window created by dumb Bhavin.");
switch (message)
{
case WM_CREATE:
button = CreateWindow(_T("BUTTON"),_T("1") ,WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 100, 40, 50, 30, hWnd, (HMENU)1, NULL, NULL);
break;
//////////////////////////////////THIS IS WHERE THE ISSUE IS///////////////////////////////////////////
case WM_COMMAND:
{
if (LOWORD(wParam) == 1)
{
OutputDebugString(_T("The compiler executes this! That means the button is working"));
MessageBox(NULL, L"Here it is", L"ok", NULL); //Message box does not appear at all. The code below it does not execute at all.
OutputDebugString(_T("The compiler DOES NOT execute this!"));
}
break;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
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;
}
return 0;
}
Edit 1:
Here is a small video of what exactly happens.
Error Video
Note : I passed hWnd parameter in this instead of NULL. Passing hWnd as first Parameter does not help either.
The issue was my half-implemented WM_Paint. Uncommenting the BeginPaint line solves the problem.
or, passing it directly to DefWindowProc as return DefWindowProc(hWnd, message, wParam, lParam); works too.

using modulus to find out if number is divisible by variable not working

I have a problem with using the % operator. This is hard to explain, so I'll just show my code first.
#include <windows.h>
const char ClassName[] = "WindowClass";
int divisible = 1;
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 50, NULL);
break;
case WM_TIMER:
{
if (divisible % 15 == 0) {
MessageBox(hwnd, "a", "a", MB_ABORTRETRYIGNORE | MB_ICONASTERISK);
}
divisible++;
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
HWND hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_SHIELD);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
wc.hIconSm = LoadIcon(NULL, IDI_SHIELD);
RegisterClassEx(&wc);
hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
ClassName,
"Tank Survival",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 820, 642,
NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while (GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
So what happens is that the messagebox in WM_TIMER repeats every time WM_TIMER is called although it should only run every 15 times WM_TIMER is called.
Any help would be appreciated.
Thanks!
Well, some good points have been made in the comments, but the essential problem here is that Windows continues to dispatch messages (including WM_TIMER messages) while the message box is on the screen so you end up recursively calling MessageBox each time the timer fires (but, since these are all on top of one another, you only see the one).
One way to resolve this is to kill the timer while the message box is on the screen, like so:
case WM_TIMER:
{
if (divisible % 15 == 0) {
KillTimer (hwnd, 1);
MessageBox (hwnd, "a", "a", MB_ABORTRETRYIGNORE | MB_ICONASTERISK);
SetTimer (hwnd, 1, 50, NULL);
}
divisible++;
break;
}
But you should debug this before you change the code, so that you fully understand what's going on.

Error using RegisterClassEx

I am trying to learn Win32 through msdn but I am having problems with RegisterClassEx, I checked other threads stating that maybe not all members are initialized but I am sure they are.
#include <Windows.h>
#include <tchar.h>
static const TCHAR windowclass_sz[] = _T("WindowClass1");
static const TCHAR windowtitle_sz[] = _T("DirectX 12 Demo");
bool Stop = true;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE PrevhInstance, LPSTR
lpCmdLine, int nCmdShow)
{
MSG msg;
HWND hWnd;
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
wcex.hInstance = hInstance;
wcex.lpfnWndProc = WndProc;
wcex.lpszClassName = windowclass_sz;
wcex.lpszMenuName = nullptr;
wcex.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&wcex);
if (!RegisterClassEx(&wcex))
{
GetLastError();
MessageBox(NULL, _T("RegisterClassEx Call Error!"), _T("ERROR"),
MB_ICONERROR && MB_OK );
return 1;
}
hWnd = CreateWindowEx(NULL, windowclass_sz, windowtitle_sz,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
800, 600, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
MessageBox(NULL, _T("CreateWindowEx Call Error!"), _T("ERROR"),
MB_ICONERROR && MB_OK);
return 1;
}
else
{
Stop = false;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
while (Stop == false)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
As you can see, the RegisterClassEx error is triggered but I have no clue what is wrong.
A message box pops up with "RegisterClassEx Call Error!" and so the program ends there, what is the problem here?
You are calling RegisterClassEx twice with the same argument. The second call will fail, since the class already exists, and GetLastError returns error code 1410 (ERROR_CLASS_ALREADY_EXISTS)1).
Solution: Register any given window class at most once.
1) You can convert error codes into human-readable representations by calling FormatMessage. Working sample code is available in this answer.

winapi doesn't respond to keypress

I recently decided to learn a bit of WinApi, but I hit a snag. I want to display a massage in my window after a keypress, but it doesn't seem to work. If I press the key multiple times or if I hold it down, still nothing happens. Can you tell me what I'm doing wrong?
This is the full code:
#include <windows.h>
#include <string.h>
#include <stdlib.h>
#include <tchar.h>
LRESULT CALLBACK WndProc (HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
LPCWSTR display_str = L"hello";
switch(uMsg)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
if(GetAsyncKeyState(VK_UP))
{
TextOut(hdc,
15, 15,
display_str,
_tcslen(display_str));
}
EndPaint(hwnd, &ps);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hwnd;
MSG uMsg;
HINSTANCE hInst;
WNDCLASSEX wcex;
LPCWSTR class_name = L"myWindowClass";
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = class_name;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
if(!RegisterClassEx(&wcex))
{
MessageBox(NULL, L"Call to RegisterClassEx failed!", L"Win32 Guided Tour!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
hInst = hInstance;
hwnd = CreateWindowEx(
NULL,
class_name,
L"Test",
WS_OVERLAPPEDWINDOW,
200, 200,
740, 540,
NULL,
NULL,
hInstance,
NULL
);
if(!hwnd)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&uMsg, NULL, 0, 0) > 0)
{
TranslateMessage(&uMsg);
DispatchMessage(&uMsg);
}
return uMsg.wParam;
}
Windows sends WM_KEYDOWN message when a key is pressed. In WndProc handle WM_KEYDOWN message, call InvalidateRect with the Client rect of the window and draw the text you want to display in WM_PAINT message handler.
Here's my example, if pressed F11 key, print in console string.:
case WM_KEYDOWN:
if(wParam==VK_F11)
{
std::cout << "Hello in my example!";
}
break;

Fade Windows Desktop in C++

I am trying to work out how to fade out or dim the Windows Desktop and then display a rectangular portion of the desktop normally. This is for a screen area capture program. You can see the precise effect I am after in Jing Fading the background in a Web page is also commonly done. Any tips/pointers/C++ source much appreciated. Google has not helped so far.
Thanks,
Neville
Use a layered window that covers the entire screen, but paint it with color key values such that the rectangular region of interest (the area that should be undarkened) is filled entirely with the color key. This region will then be completely transparent, and not darkened like the rest of the desktop. The rest of your layered window should be set to have a constant alpha value that is mostly transparent and filled with a dark color.
Here's a complete, working example:
#include "stdafx.h"
#include "ScreenCapper.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
const COLORREF transparentColor = RGB(255,0,0); // Pure red is the color key, or totally transparent color
const BYTE overallTranparencyAmount = 90; // Out of 255
int DesktopWidth,DesktopHeight;
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
DesktopWidth = GetSystemMetrics(SM_CXSCREEN);
DesktopHeight = GetSystemMetrics(SM_CYSCREEN);
MSG msg;
HACCEL hAccelTable;
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_SCREENCAPPER, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_SCREENCAPPER));
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
memset(&wcex,0,sizeof(WNDCLASSEX));
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SCREENCAPPER));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
//wcex.lpszMenuName = MAKEINTRESOURCE(IDC_SCREENCAPPER);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance;
HWND hWnd = CreateWindowEx(WS_EX_LAYERED, szWindowClass, szTitle,WS_POPUP, 0, 0, DesktopWidth, DesktopHeight, NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
SetLayeredWindowAttributes(hWnd,transparentColor,32,LWA_COLORKEY | LWA_ALPHA);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
if (message == WM_COMMAND)
{
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
else if (message == WM_PAINT)
{
hdc = BeginPaint(hWnd, &ps);
HBRUSH hDarkBackgroundBrush = CreateSolidBrush(RGB(0,0,0));
HBRUSH hRegionOfInterestBrush = CreateSolidBrush(transparentColor);
RECT screenRect;
screenRect.left = screenRect.top = 0;
screenRect.right = DesktopWidth;
screenRect.bottom = DesktopHeight;
RECT interestRect;
interestRect.left = interestRect.top = 300;
interestRect.right = interestRect.bottom = 600;
FillRect(hdc,&screenRect,hDarkBackgroundBrush);
FillRect(hdc,&interestRect,hRegionOfInterestBrush);
DeleteObject(hDarkBackgroundBrush);
DeleteObject(hRegionOfInterestBrush);
EndPaint(hWnd, &ps);
}
else if (message == WM_DESTROY)
{
PostQuitMessage(0);
}
else
return DefWindowProc(hWnd, message, wParam, lParam);
return 0;
}
The official way is with FadeWindow() api :
Windows does that on Display Control Panel
See the standard code in C