Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

CheckBox Transparent

10 réponses
Avatar
Victor
Bonjour,

Je cherches à rendre un radio et un checkbox transparent.
Le fond est une image BMP.

Si je traite comme un static sans les thèmes XP ça fonctionne mais dès que
je les active, j'ai deux problème :
- le fond du radio reprend le fond de la fenêtre mais à partir du haut
- le fond du checkbox est noir ainsi que le texte.

Pourtant je n'ai pas changé de code et j'utilise la méthode du
WM_CTLCOLORSTATIC.

Merci de m'aider et bonne prog,
@++

Victor

10 réponses

Avatar
Christian ASTOR
Victor wrote:

Bonjour,

Je cherches à rendre un radio et un checkbox transparent.
Le fond est une image BMP.

Si je traite comme un static sans les thèmes XP ça fonctionne mais dès que
je les active, j'ai deux problème :
- le fond du radio reprend le fond de la fenêtre mais à partir du haut
- le fond du checkbox est noir ainsi que le texte.

Pourtant je n'ai pas changé de code et j'utilise la méthode du
WM_CTLCOLORSTATIC.

Merci de m'aider et bonne prog,



Quand c'est "themed", il faut appeler DrawThemeParentBackground()
Avatar
Victor
> Quand c'est "themed", il faut appeler DrawThemeParentBackground()



Bonjour,

Merci bien pour ta réponse mais les exemples sans MFC ne sont pas courants
sur le web.
Peux-tu m'aider à transformer ce code en API Win32 que j'ai pris sur un site
dont le code source est public, sur ce code si on active les thème le static
est noir au lieu d'avoir le fond voulu :
----------------------------------------
#include <windows.h>

// Déclarations globales:
WNDPROC oldstaticproc,oldeditproc;
HDC hdcmem;

// Procédure de sous-classement du Static:
LRESULT CALLBACK staticproc(HWND hwnd,UINT msg,WPARAM wParam, LPARAM lParam)
{
if(msg==WM_ERASEBKGND)
{
POINT pt;
RECT rect;
GetClientRect(hwnd,&rect);// Obtenir les coordonnées de la zone cliente
pt.x=rect.left; pt.y=rect.top;
ClientToScreen(hwnd,&pt);// Les traduire en coordonnées écran
ScreenToClient(GetParent(hwnd),&pt);// Les traduire en coordonnées fenêtre
parente
// Dessiner la portion du fond correspondante:
BitBlt((HDC)wParam,0,0,rect.right,rect.bottom,hdcmem,pt.x,pt.y,SRCCOPY);
return 1;
}
return CallWindowProc(oldstaticproc, hwnd, msg, wParam, lParam);
}

// Procédure de sous-classement de l'Edit:
LRESULT CALLBACK editproc(HWND hwnd,UINT msg,WPARAM wParam, LPARAM lParam)
{
if(msg==WM_ERASEBKGND)
{
POINT pt;
RECT rect;
GetClientRect(hwnd,&rect);// Obtenir les coordonnées de la zone cliente
pt.x=rect.left; pt.y=rect.top;
ClientToScreen(hwnd,&pt);// Les traduire en coordonnées écran
ScreenToClient(GetParent(hwnd),&pt);// Les traduire en coordonnées fenêtre
parente
// Dessiner la portion du fond correspondante:
BitBlt((HDC)wParam,0,0,rect.right,rect.bottom,hdcmem,pt.x,pt.y,SRCCOPY);
return 1;
}
return CallWindowProc(oldeditproc, hwnd, msg, wParam, lParam);
}

// Procédure de la fenêtre principale:
LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam, LPARAM lParam)
{
static HBITMAP hbmp;
static HWND hedit,hstatic,hquitter;
static char buffer[100];
switch (msg)
{
case WM_CREATE:
// Création des contrôles:
hstatic=CreateWindowEx(0,"static",0,WS_VISIBLE | WS_CHILD |
SS_CENTER,30,60,300,20,hwnd,0,0,0);
oldstaticproc=(WNDPROC)SetWindowLong(hstatic,GWL_WNDPROC,(long)staticproc);
hedit=CreateWindowEx(WS_EX_CLIENTEDGE,"edit",0,WS_VISIBLE | WS_CHILD
,30,130,300,20,hwnd,0,0,0);
oldeditproc=(WNDPROC)SetWindowLong(hedit,GWL_WNDPROC,(long)editproc);
hquitter=CreateWindowEx(0,"button","Quitter",WS_VISIBLE | WS_CHILD
,140,190,80,20,hwnd,0,0,0);
// Créer le Device Context en mémoire:
hdcmem = CreateCompatibleDC(0);
// Charger le bitmap de fond depuis les ressources de l'exécutable:
hbmp = LoadBitmap(GetModuleHandle(0), "IDB_BMP");
// Sélectionner ce bitmap pour le HDC en mémoire:
SelectObject(hdcmem, hbmp);
return 0;

case WM_CTLCOLORSTATIC:
case WM_CTLCOLOREDIT:
// Définir le mode comme transparent:
SetBkMode((HDC)wParam,TRANSPARENT);
// Définir la couleur de texte (jaune):
SetTextColor((HDC)wParam,RGB(255,255,0));
// Retourner le HBRUSH de transparence:
return (LRESULT)GetStockObject(NULL_BRUSH);

case WM_PAINT:
PAINTSTRUCT ps;
HDC hdc;
hdc¾ginPaint(hwnd,&ps);
// Afficher l'image de fond sur la surface de la fenêtre:
BitBlt(hdc,0,0,360,270,hdcmem,0,0,SRCCOPY);
EndPaint(hwnd,&ps);
return 0;

case WM_COMMAND:
if(HIWORD(wParam)==EN_CHANGE)
{
// Redessiner l'Edit après chaque modification:
InvalidateRect((HWND)lParam,0,1);
// Récupérer le texte de l'Edit:
GetWindowText((HWND)lParam,buffer,100);
// Le transmettre au Static:
SetWindowText(hstatic,buffer);
// Redessiner le Static:
InvalidateRect(hstatic,0,1);
return 0;
}
if((HWND)lParam==hquitter) SendMessage(hwnd,WM_CLOSE,0,0);
return 0;

case WM_CLOSE:
DeleteDC(hdcmem);
DeleteObject(hbmp);
DestroyWindow(hwnd);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;
default:
break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}


int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR cmd,int show)
{
// Déclaration et initialisation de la strucrure WNDCLASSEX:
WNDCLASSEX wc;
memset(&wc,0,sizeof(wc));
wc.cbSize=sizeof(WNDCLASSEX);
wc.hInstance=hInst;
wc.lpfnWndProc=WndProc;
wc.hCursor=LoadCursor(0,IDC_ARROW);
wc.hbrBackground=0;
wc.lpszClassName=TEXT("mafenetre");
// Enregistrement de notre classe de fenêtre:
RegisterClassEx(&wc);
// Creéation et affichage de la fenêtre:
HWND hwnd=CreateWindowEx(0,"mafenetre","Edit et Static transparents sur
fond BMP", WS_SYSMENU | WS_MINIMIZEBOX,0,0,366,296,0,0,0,0);
ShowWindow(hwnd,1);
UpdateWindow(hwnd);
MSG Msg;
// Boucle des messages:
while (GetMessage(&Msg, 0, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0;
}
------------------------------------------------------------------------------

Merci encore et bonne prog,

@++,

Victor
Avatar
Victor
Désolé c'est l'édit qui est noir
Avatar
Christian ASTOR
On 16 mar, 23:40, "Victor" wrote:

Merci bien pour ta réponse mais les exemples sans MFC ne sont pas coura nts
sur le web.
Peux-tu m'aider à transformer ce code en API Win32 que j'ai pris sur un site
dont le code source est public, sur ce code si on active les thème le s tatic
est noir au lieu d'avoir le fond voulu :



Ce code n'est pas très bon.
On n'a pas besoin de subclasser les static controls.
Il faut appeler DrawThemeParentBackground() dans WM_CTLCOLORSTATIC et
dessiner dans WM_PRINTCLIENT + WM_PAINT (avec une même fonction en
distinguant le DC (celui de wParam ou de BeginPaint())
Pour les Edit controls, pas besoin de WM_CTLCOLOREDIT, le plus simple
est de les remplacer par des RichEdit controls en subclassant et
traitant WM_CHAR, comme dans la KB639660 italienne..
Avatar
Victor
> Ce code n'est pas très bon.
On n'a pas besoin de subclasser les static controls.
Il faut appeler DrawThemeParentBackground() dans WM_CTLCOLORSTATIC et
dessiner dans WM_PRINTCLIENT + WM_PAINT (avec une même fonction en
distinguant le DC (celui de wParam ou de BeginPaint())
Pour les Edit controls, pas besoin de WM_CTLCOLOREDIT, le plus simple
est de les remplacer par des RichEdit controls en subclassant et
traitant WM_CHAR, comme dans la KB639660 italienne..



Le but est à partir de ce code, le modifier pour ensuite dessinner toutes
sortes de contrôles transparent edit, static, checkbox sans modifier le code
et sans dessiner tout soi même.
Parce que un WM_PAINT c'est bien mais pour dessiner le contenu d'un edit et
gérer ce qu'il y a dedans c'est plus simple de le rendre transparent et de
laisser Windows faire le reste.

Sinon je ne connais pas l'italien.

Merci du temps que tu passes à me répondre.
Avatar
Victor
J'ai oublié de préciser que je code sans MFC, ATL et autres trucs Visual
Studio.
Je suis sous Dev-C++ et utilise en direct les API mais sans réinventer la
roue en gérant les inputs pour afficher (c'est trop fastidieux).
Avatar
Christian ASTOR
On 17 mar, 17:26, "Victor" wrote:

Le but est à partir de ce code, le modifier pour ensuite dessinner tout es
sortes de contrôles transparent edit, static, checkbox sans modifier le code
et sans dessiner tout soi même.
Parce que un WM_PAINT c'est bien mais pour dessiner le contenu d'un edit et
gérer ce qu'il y a dedans c'est plus simple de le rendre transparent et de
laisser Windows faire le reste.



Oui, c'est bien ce que j'avais compris.
Je parlais du WM_PAINT de la fenêtre principale (pour blitter une
bitmap en fond par exemple), pas des childs.
J'ai refait un test sous XP avec Static, Radio, Checkbox, RichEdit et
la transparence marche bien, avec ou sans Manifest (avec par ex
DllGetVersion() sur "comctl32.dll" pour tester si Manifest et ne pas
appeler DrawThemeParentBackground())

Sinon je ne connais pas l'italien.



Moi non plus, mais l'important c'est le code de cette KB pour la
transparence du RichEdit avec WS_EX_TRANSPARENT :

case WM_CHAR:
{
RECT rect;
GetClientRect(hwnd, &rect);
ClientToScreen(hwnd, (LPPOINT)&rect);
ScreenToClient(GetParent(hwnd),(LPPOINT) &rect);
InvalidateRect(GetParent(hwnd), &rect, TRUE);
}
break;
Avatar
Victor
> Oui, c'est bien ce que j'avais compris.
Je parlais du WM_PAINT de la fenêtre principale (pour blitter une
bitmap en fond par exemple), pas des childs.
J'ai refait un test sous XP avec Static, Radio, Checkbox, RichEdit et
la transparence marche bien, avec ou sans Manifest (avec par ex
DllGetVersion() sur "comctl32.dll" pour tester si Manifest et ne pas
appeler DrawThemeParentBackground())



As-tu un exemple complet à me proposer compilable avec g++ ? comme celui que
tu fais dans ta description ?

Merci encore et bonne prog,

@++,

Victor
Avatar
Christian ASTOR
On 17 mar, 20:00, "Victor" wrote:

As-tu un exemple complet à me proposer compilable avec g++ ? comme celu i que
tu fais dans ta description ?



Un petit exemple Win32 Unicode, compilé avec VS.NET 2003 sous XP SP2
(en fait il n'y a apparemment même pas besoin de subclasser le
RichEdit en version > 1, WS_EX_TRANSPARENT semble suffisant)
J'ai mis pour le test, en mosaique du background (loop BitBlt()), la
bitmap d'ID 1678 de rasdlg.dll, car elle est normalement présente
partout (sinon, en Loader une autre...) =>

#define UNICODE
#define _UNICODE

#include <windows.h>
#include <tchar.h>

#include <uxtheme.h>
#include <TmSchema.h>
#pragma comment(lib, "UxTheme")
#include <shlwapi.h>
#include <richedit.h>

HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void Paint(HWND hWnd, HDC hDC, HBITMAP hBitmap);
LRESULT OldEditProc;
LRESULT CALLBACK EditProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
lParam);

int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
hInst = hInstance;
WNDCLASSEX wcex = { sizeof(WNDCLASSEX), 0, WndProc, 0, 0, hInst,
LoadIcon(NULL,
IDI_APPLICATION), LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW
+ 1), NULL, L"Transp", NULL, };
if(!RegisterClassEx(&wcex))
return MessageBox(NULL, L"Cannot register class !", L"Error",
MB_ICONERROR | MB_OK);
int nX = (GetSystemMetrics(SM_CXSCREEN) - 470) / 2, nY =
(GetSystemMetrics(SM_CYSCREEN) - 300) / 2;
HWND hWnd = CreateWindowEx(0, wcex.lpszClassName, L"Test
Transparency", WS_OVERLAPPEDWINDOW, nX, nY, 470, 300, NULL, NULL,
hInst, NULL);
if(!hWnd)
return MessageBox(NULL, L"Cannot create window !", L"Error",
MB_ICONERROR | MB_OK);
ShowWindow(hWnd, SW_SHOWNORMAL);
UpdateWindow(hWnd);
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}


LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam)
{
static HWND hStatic1, hRadio1, hRadio2, hCheck1, hEdit1;
static HBITMAP hBitmap;
static BOOL bTheme = 0;

switch (message)
{
case WM_CREATE:
{
hStatic1 = CreateWindowEx(0, TEXT("STATIC"), TEXT("Test Static"),
WS_CHILD | WS_VISIBLE| ES_LEFT,
10, 10, 100, 16, hWnd, (HMENU)10, hInst, NULL);
hCheck1 = CreateWindow(TEXT("BUTTON"), TEXT("Test Checkbox"),
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTOCHECKBOX,
130, 5, 120, 32, hWnd, (HMENU)11, hInst, NULL);
hRadio1 = CreateWindow(TEXT("BUTTON"), TEXT("Radio 1"),
WS_VISIBLE |WS_CHILD | BS_AUTORADIOBUTTON,
270, 10, 80, 20, hWnd, (HMENU)12, hInst, NULL);
hRadio2 = CreateWindow(TEXT("BUTTON"), TEXT("Radio 2"),
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_AUTORADIOBUTTON,
370, 10, 80, 20, hWnd, (HMENU)13, hInst, NULL);
HMODULE hLib = LoadLibrary(TEXT("RichEd20.dll"));
hEdit1 = CreateWindowEx(WS_EX_TRANSPARENT, RICHEDIT_CLASS, TEXT
("Test RichEdit"),
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_BORDER | WS_VSCROLL |
WS_HSCROLL | ES_AUTOVSCROLL | ES_MULTILINE | ES_AUTOHSCROLL,
10, 60, 440, 150, hWnd, (HMENU)20, hInst, NULL);
HINSTANCE hInst = LoadLibrary(TEXT("comctl32.dll"));
if (hInst)
{
DLLGETVERSIONPROC pfnVersion;
pfnVersion = (DLLGETVERSIONPROC)GetProcAddress(hInst,
"DllGetVersion");
if (pfnVersion)
{
DLLVERSIONINFO vi;
vi.cbSize = sizeof(DLLVERSIONINFO);
if (SUCCEEDED(pfnVersion(&vi)))
{
if (vi.dwMajorVersion >= 6)
bTheme = 1;
}
}
}
HINSTANCE hInstBitmap = LoadLibrary(TEXT("rasdlg.dll"));
hBitmap = LoadBitmap(hInstBitmap, MAKEINTRESOURCE(1678));
}
break;
case WM_CTLCOLORSTATIC :
{
HDC hDC = (HDC)wParam;
HWND hWnd = (HWND)lParam;
SetBkMode(hDC, TRANSPARENT);
RECT rc;
GetClientRect(hWnd, &rc);
if (bTheme)
DrawThemeParentBackground(hWnd, hDC, &rc);
return (LRESULT)GetStockObject( HOLLOW_BRUSH );
}
break;
case WM_PRINTCLIENT:
case WM_PAINT:
Paint(hWnd, (HDC)wParam, hBitmap);
break;
case WM_DESTROY:
{
if (hBitmap)
DeleteObject(hBitmap);
PostQuitMessage(0);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

void Paint(HWND hWnd, HDC hDC, HBITMAP hBitmap)
{
PAINTSTRUCT ps;
HDC hDCPaint;
if (hDC)
hDCPaint = hDC;
else
{
BeginPaint(hWnd, &ps );
hDCPaint = ps.hdc;
}
RECT rect;
GetClientRect(hWnd, &rect);
if (hBitmap)
{
HDC hDCMem = CreateCompatibleDC(hDC);
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDCMem, hBitmap);
BITMAP bm;
GetObject(hBitmap, sizeof(BITMAP), &bm );
for (int y = 0; y < rect.bottom; y += bm.bmHeight)
for (int x = 0; x < rect.right; x += bm.bmWidth )
BitBlt(hDCPaint, x, y, bm.bmWidth, bm.bmHeight, hDCMem, 0, 0,
SRCCOPY);
SelectObject(hDCMem, hBitmapOld);
DeleteDC(hDCMem);
}
else
FillRect(hDCPaint, &rect, (HBRUSH)(COLOR_3DFACE + 1));
if (!hDC)
EndPaint(hWnd, &ps);
}
Avatar
Victor
Bonjour,

Merci beaucoup ça m'a l'air de fonctionner impeccablement.

Bonne prog,

@++,

Victor