首先,這個問題可能是重復的,但問題沒有足夠的資訊來解決問題。
我的本機 Win32 應用程式中有兩個視窗。第一個是WS_EX_NOACTIVATE擴展樣式的分層視窗,第二個是普通視窗。我希望分層的是不可激活的。問題是,當我在同一個應用程式中有兩個視窗時,必須是不可激活的分層視窗在它們之間切換時會被激活。但是在兩個外部視窗之間切換時沒有問題,一個不屬于我的應用程式。我怎么解決這個問題?或者我可以解決嗎?有什么我錯過的嗎?以下是一個最小的可重現示例(不包括任何最小性錯誤檢查。)感謝您抽出寶貴的時間。
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void init_device_resources(int cx, int cy, void** rgb);
void update_content();
void set_window_size(int width, int height);
HWND layeredhWnd;
HWND otherhWnd;
WNDCLASSEX wc;
MSG msg;
HDC hdcDesktop;
HDC hdcContent;
POINT dstPoint = { 100, 100 };
SIZE windowSize = { 800, 600 };
BLENDFUNCTION bf;
BITMAPINFO bi;
BYTE* rgb_data = NULL;
HBITMAP hBitmap;
HBITMAP hOldBitmap;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"LayeredWindowClass";
RegisterClassEx(&wc);
wc.lpszClassName = L"OtherWindowClass";
RegisterClassEx(&wc);
layeredhWnd = CreateWindowEx(WS_EX_LAYERED | WS_EX_NOACTIVATE,
L"LayeredWindowClass",
L"",
WS_POPUP | WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_THICKFRAME,
0, 0,
800, 600,
NULL,
NULL,
hInstance,
NULL);
otherhWnd = CreateWindowEx(NULL,
L"OtherWindowClass",
L"",
WS_OVERLAPPEDWINDOW,
0, 0,
800, 600,
NULL,
NULL,
hInstance,
NULL);
init_device_resources(800, 600, &rgb_data);
set_window_size(800, 600);
ShowWindow(layeredhWnd, nCmdShow);
ShowWindow(otherhWnd, nCmdShow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
case WM_ACTIVATE:
{
if(hWnd == layeredhWnd)
update_content();
break;
}
case WM_PAINT:
{
if (hWnd == layeredhWnd)
update_content();
break;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
void init_device_resources(int cx, int cy, void** rgb)
{
hdcDesktop = GetDC(NULL);
hdcContent = CreateCompatibleDC(hdcDesktop);
bf.BlendOp = AC_SRC_OVER;
bf.BlendFlags = 0;
bf.SourceConstantAlpha = 255;
bf.AlphaFormat = AC_SRC_ALPHA;
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = cx;
bi.bmiHeader.biHeight = -cy;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = cx * cy * 4;
bi.bmiHeader.biXPelsPerMeter = 0;
bi.bmiHeader.biYPelsPerMeter = 0;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
bi.bmiColors[0] = (RGBQUAD){ 0 };
hBitmap = CreateDIBSection(hdcContent, &bi, DIB_RGB_COLORS, rgb, NULL, 0);
for (int i = 0; i < cx * cy * 4; i )
{
rgb_data[i] = 255;
}
hOldBitmap = SelectObject(hdcContent, hBitmap);
}
void update_content()
{
UpdateLayeredWindow(layeredhWnd, hdcDesktop, &dstPoint,
&windowSize, hdcContent, &(POINT){ 0, 0 }, RGB(0, 0, 0), & bf, ULW_ALPHA);
}
void set_window_size(int width, int height)
{
SetWindowPos(layeredhWnd, NULL, 0, 0, width, height, SWP_NOMOVE);
windowSize = (SIZE){ width, height };
}
uj5u.com熱心網友回復:
雖然我仍然不明白問題的原因,但在@IInspectable 的指導和檔案的幫助下,我能夠通過處理WM_MOUSEACTIVATE訊息來防止視窗被激活。更新的視窗程序如下。
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
{
DestroyWindow(hWnd);
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
break;
}
case WM_MOUSEACTIVATE:
{
if (hWnd == layeredhWnd)
return MA_NOACTIVATE;
break;
}
case WM_ACTIVATE:
{
if(hWnd == layeredhWnd)
update_content();
break;
}
case WM_PAINT:
{
if (hWnd == layeredhWnd)
update_content();
break;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/406606.html
標籤:
