1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| /* "Fenêtre transparente"
https://www.developpez.net/forums/d1645255/c-cpp/cpp/api-win32-redessiner-bureau-windows/#post8994319
Résultat du test: WS_EX_TRANSPARENT ne suffit pas car il ne s'applique qu'aux fenêtres du même thread.
*/
#define _WIN32_WINNT 0x501 /*Windows XP ou supérieur (pour ICC_STANDARD_CLASSES)*/
#include <windows.h>
#pragma warning(push)
#pragma warning(disable: 4201) /*Supprime un warning inutile sous Visual 2005*/
#include <commctrl.h>
#pragma warning(pop)
/*#pragma comment(lib, "comctl32.lib")*/
/*#define HMENU_FROM_CONTROLID(x) ((HMENU)(INT_PTR)(x))*/
/*Pour avoir un affichage moderne, il faut compiler en UNICODE et utiliser Common Controls v6 ou supérieur*/
#ifdef UNICODE
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
/*This style is from the Vista SDK, Visual Studio 2008.*/
#ifndef WS_EX_LAYERED
#define WS_EX_LAYERED 0x00080000
BOOL WINAPI SetLayeredWindowAttributes(
_In_ HWND hwnd,
_In_ COLORREF crKey,
_In_ BYTE bAlpha,
_In_ DWORD dwFlags
);
#define LWA_COLORKEY 0x00000001
#endif
/*Procédure de fenêtre*/
LRESULT CALLBACK transparent_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT ret = 0;
switch(uMsg)
{
case WM_CREATE:
{
SetLayeredWindowAttributes(hWnd, RGB(0,255,0), 255, LWA_COLORKEY);
}
break;
/*Finir la boucle de messages quand cette fenêtre est détruite*/
/*Note: Pour bien faire, je devrais aussi re-changer la police des contrôles et la détruire.
Mais j'ai la flemme et le processus est sur le point de se terminer de toute façon.*/
case WM_DESTROY: PostQuitMessage(0); break;
case WM_NCHITTEST:
ret = DefWindowProc(hWnd, uMsg, wParam, lParam);
if(ret == HTCLIENT)
ret = HTTRANSPARENT;
break;
case WM_ERASEBKGND:
{
RECT r;
HBRUSH hbr = CreateSolidBrush(RGB(0,255,0));
GetClientRect(hWnd, &r);
FillRect((HDC)wParam, &r, hbr);
DeleteObject(hbr);
ret = TRUE;
}
break;
default:
ret = DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
return ret;
}
int APIENTRY transparent_WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
HWND hWnd = NULL;
WNDCLASSEX wcx={0};
/*INITCOMMONCONTROLSEX icex = { sizeof icex, ICC_STANDARD_CLASSES };*/
(void)hPrevInstance;
(void)lpCmdLine;
(void)nShowCmd;
/*Initialisation des Common Controls et des Visual Styles*/
/*InitCommonControlsEx(&icex);*/
/*Définir la classe de fenêtre*/
wcx.cbSize = sizeof wcx;
wcx.hbrBackground = NULL;
wcx.hInstance = hInstance;
wcx.lpfnWndProc = transparent_WindowProc;
wcx.lpszClassName = TEXT("Transparent Window");
wcx.hCursor = LoadCursor(NULL, IDC_ARROW);
wcx.style = CS_HREDRAW|CS_VREDRAW; /*Ils semblent être nécessaires en fait, sinon les contrôles se redessinent mal (j'ai l'impression qu'ils se redessinent trop tôt)...*/
if(RegisterClassEx(&wcx) == 0)
return EXIT_FAILURE;
hWnd = CreateWindowEx(WS_EX_LAYERED, wcx.lpszClassName, TEXT("Fenêtre Transparente"), WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if(hWnd != NULL)
{
/*Boucle de messages*/
MSG msg = {0};
while(GetMessage(&msg, NULL, 0, 0)>0) /*Attente bloquante, dispatche tous les messages 'envoyés' et récupère le premier message 'posté' de la file du thread courant*/
{
TranslateMessage(&msg); /*Génère les WM_CHAR à partir des WM_KEYDOWN (les insère en tête de file)*/
DispatchMessage(&msg); /*Dispatche message récupéré vers la bonne procédure de fenêtre*/
}
}
return 0;
} |