Greenhorn Posted March 18, 2008 Share Posted March 18, 2008 (edited) Moin Moin,I'm a totally Rookie in DLLCall's and in GuiRegisterMsg, and I'm at the point to give up ... oOMaybe an expert will take notice of my problem.I want to change the background color of a RadioButton or CheckBox. (to transparent ...)The working C++ code I investigated and tested is below, it works. (also with non-owner drawn)My problem is to get it in AutoIt working. I try it since two weeks without any (good) results, strictly speaking: no results.But instead of this I've got bloody eyes by Google and a lot of frustration ... I think that $lParam is the problem. If I make an output to the Console I get always the number 309 for $lParam, but it should be a hWnd from the button ...The C++ code in the 'WndProc' looks like this:case WM_CTLCOLORSTATIC: //Message abfangen , hooking message ... SetTextColor((HDC)wParam,RGB(255,255,255)); //weiß , white SetBkMode((HDC)wParam,TRANSPARENT); //farblos , uncolored return (LRESULT)GetStockObject(NULL_BRUSH); //kein HBRUSH zurückgeben , don't return a HBRUSHMy tries ...expandcollapse popup#include <GUIConstants.au3> #Include <WinAPI.au3> ;GUIRegisterMsg($WM_CTLCOLORSTATIC, 'WM_CTLCOLORSTATIC') GUIRegisterMsg($WM_CTLCOLORBTN, 'WM_CTLCOLORBTN') $hWndMain = GUICreate("My CheckBox Button with Transparency", 300, 200, _ -1, -1, _ $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x00ff00) $pic = GUICtrlCreatePic(@SystemDir & '\oobe\images\wpaback.jpg', 0, 0, 300, 200) GUICtrlSetState(-1, $GUI_DISABLE) ; this button should have a transparent background, but it hasn't ... $btnCheckBox = GUICtrlCreateCheckbox('Checkbox', 100, 90, 100, 20) $btnPushButton = GUICtrlCreateButton('PushButton', 110, 150, 80, 20) ; will we see the pic instead of green ... ? I don't think so ... :( GUISetState() While True Switch GUIGetMsg() Case -3 Exit EndSwitch WEnd ;======================================================================================== ; WM_CTLCOLORBTN Notification ; [url="http://msdn2.microsoft.com/en-us/library/bb761849%28VS.85%29.aspx"]http://msdn2.microsoft.com/en-us/library/b...849(VS.85).aspx[/url] ; The WM_CTLCOLORBTN message is sent to the parent window of a button before ; drawing the button. The parent window can change the button's text and background ; colors. However, only owner-drawn buttons respond to the parent window ; processing this message. ; ; Syntax ; WM_CTLCOLORBTN(WPARAM wParam, LPARAM lParam) ; ; Parameters ; ; wParam ; A handle to the display context for the button. ; lParam ; A handle to the button. ; ; Return Value ; ; If an application processes this message, it must return a handle to a brush. ; The system uses the brush to paint the background of the button. ; ; Remarks ; ; By default, the DefWindowProc function selects the default system ; colors for the button. Buttons with the BS_PUSHBUTTON, BS_DEFPUSHBUTTON, ; or BS_PUSHLIKE styles do not use the returned brush. ; Buttons with these styles are always drawn with the default system colors. ; Drawing push buttons requires several different brushes-face, highlight, ; and shadow-but the WM_CTLCOLORBTN message allows only one brush to be ; returned. To provide a custom appearance for push buttons, ; use an owner-drawn button. ; The WM_CTLCOLORBTN message is never sent between threads. It is sent only ; within one thread. ; The text color of a check box or radio button applies to the box or button, ; its check mark, and the text. The focus rectangle for these buttons remains ; the system default color (typically black). The text color of a group box ; applies to the text but not to the line that defines the box. ; The text color of a push button applies only to its focus rectangle ; ; it does not affect the color of the text. ; If a dialog box procedure handles this message, it should cast the desired ; return value to a BOOL and return the value directly. If the dialog box ; procedure returns FALSE, then default message handling is performed. ; The DWL_MSGRESULT value set by the SetWindowLong function is ignored. ;======================================================================================== Func WM_CTLCOLORBTN($wParam, $lParam) #forceref $wParam, $lParam $hDC = _WinAPI_GetDC($wParam) If $lParam = GUICtrlGetHandle($btnCheckBox) Then ;SetBkMode((HDC)wParam, TRANSPARENT); // C++ code SetBkMode($hDC, 1) ; 1 = TRANSPARENT ConsoleWrite('$hDC = ' & $hDC & @CRLF & _ '$lParam = ' & $lParam & @CRLF & _ ; this output should be a handle ??? '$wParam = ' & $wParam & @CRLF) ; this looks like a handle, ; but always the same ? Return _WinAPI_GetStockObject('HOLLOW_BRUSH') ; should I return it as a 'long', how ? ;Return (LRESULT)_WinAPI_GetStockObject('HOLLOW_BRUSH'); // C++ code EndIf EndFunc ;======================================================================================== ; WM_CTLCOLORSTATIC($hDC, $hCtrl) ;======================================================================================== Func WM_CTLCOLORSTATIC($wParam, $lParam) #forceref $wParam, $lParam $hDC = _WinAPI_GetDC($wParam) If $lParam = GUICtrlGetHandle($btnCheckBox) Then SetBkMode($hDC, 1) ; 1 = TRANSPARENT ;SetBkMode((HDC)wParam, TRANSPARENT); // C++ code Return _WinAPI_GetStockObject('HOLLOW_BRUSH') ; ;Return (LRESULT)_WinAPI_GetStockObject('HOLLOW_BRUSH'); // C++ code EndIf EndFunc ;======================================================================================== ; Func SetBkMode() ;======================================================================================== Func SetBkMode($hDC, $flag = 0) If $flag < 0 Or $flag > 1 Then Return SetError(1) DllCall('gdi32.dll', 'int', 'SetBkMode', _ 'hwnd', $hDC, _ ; handle to Decive Context 'int', $flag) ; $flag: 1 = TRANSPARENT, 0 = OPAQUE EndFuncGreetzGreenhornEDIT: @AdminsProblems with my browser, please delete the doubled post !!! Edited March 18, 2008 by Greenhorn Link to comment Share on other sites More sharing options...
Greenhorn Posted March 18, 2008 Author Share Posted March 18, 2008 (edited) OK, I figured out, that the mysterious number '309' of the $lParam is the Const value from $WM_CTLCOLORBTN in the includes ... It should be a handle as in the description, shouldn't it ? It also seems that the WM_CTLCOLORBTN message is only sent, if I create a PushButton ... Hmmmm ... But I'm too tired today to go on ..., tomorrow the sun shines again and maybe Manitou will give me a hint and the brain to face it ... For testing the Console output try the following code Func WM_CTLCOLORBTN($wParam, $lParam) ;#forceref $wParam, $lParam $hDC = _WinAPI_GetDC($wParam) ;If $lParam = GUICtrlGetHandle($btnCheckBox) Then SetBkMode($wParam, 1) ; 1 = TRANSPARENT ;SetBkMode((HDC)wParam, TRANSPARENT); ConsoleWrite('$hDC = ' & $hDC & @CRLF & _ '$lParam = ' & $lParam & @CRLF & _ '$wParam = ' & $wParam & @CRLF) Return _WinAPI_GetStockObject('HOLLOW_BRUSH') ; ;Return (long)_WinAPI_GetStockObject('HOLLOW_BRUSH'); ;EndIf EndFunc Good night Greenhorn Edited March 19, 2008 by Greenhorn Link to comment Share on other sites More sharing options...
Greenhorn Posted March 22, 2008 Author Share Posted March 22, 2008 (edited) OK, now I got it turned to white Background, it's a little step for me, but a giant step for the world ... Well, I tried it in C++ and it definitly works, I just have to translate it in AutoIt ... So, please, could anyone take a look at this ? expandcollapse popup#include <GUIConstants.au3> #Include <WinAPI.au3> Global $OPAQUE = 0 Global $TRANSPARENT = 1 ;GUIRegisterMsg($WM_CTLCOLORSTATIC, 'WM_CTLCOLORSTATIC') GUIRegisterMsg($WM_CTLCOLORBTN, 'WM_CTLCOLORBTN') $hWndMain = GUICreate("My CheckBox Button with Transparency", 300, 200, _ -1, -1, _ $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x00ff00) $pic = GUICtrlCreatePic(@SystemDir & '\oobe\images\wpaback.jpg', 0, 0, 300, 200) GUICtrlSetState(-1, $GUI_DISABLE) ; this button should have a transparent background, but it hasn't ... $btnCheckBox = GUICtrlCreateCheckbox('Checkbox', 100, 90, 100, 20) $btnPushButton = GUICtrlCreateButton('PushButton', 110, 150, 80, 20) ; will we see the pic instead of green ... ? I don't think so ... :( GUISetState() While True Switch GUIGetMsg() Case -3 Exit EndSwitch WEnd ;======================================================================================== ; WM_CTLCOLORSTATIC($hDC, $hCtrl) ;======================================================================================== Func WM_CTLCOLORSTATIC($wParam, $lParam) #forceref $wParam, $lParam Local $hDC = $wParam ConsoleWrite('$hDC (wParam) = ' & $hDC & @CR) SetBkMode($hDC, $TRANSPARENT) Return Int(_WinAPI_GetStockObject(5)) ; 5 = NULL_BRUSH/HOLLOW_BRUSH ; working C++ code. ;HDC hDC = (HDC) wParam ; ;SetBkMode((HDC)wParam, TRANSPARENT) ; ;Return (long)_WinAPI_GetStockObject('HOLLOW_BRUSH') ; EndFunc ;======================================================================================== ; Func SetBkMode() ;======================================================================================== Func SetBkMode($hDC, $flag = 0) If $flag < 0 Or $flag > 1 Then Return SetError(1) DllCall('gdi32.dll', 'int', 'SetBkMode', _ 'hwnd', $hDC, _ ; handle to Decive Context 'int', $flag) ; $flag: 1 = TRANSPARENT, 0 = OPAQUE EndFunc #cs #define WHITE_BRUSH 0 #define LTGRAY_BRUSH 1 #define GRAY_BRUSH 2 #define DKGRAY_BRUSH 3 #define BLACK_BRUSH 4 #define NULL_BRUSH 5 #define HOLLOW_BRUSH NULL_BRUSH #define WHITE_PEN 6 #define BLACK_PEN 7 #define NULL_PEN 8 #define SYSTEM_FONT 13 #define DEFAULT_PALETTE 15 #ce Greetz Greenhorn Edited March 22, 2008 by Greenhorn Link to comment Share on other sites More sharing options...
Siao Posted March 22, 2008 Share Posted March 22, 2008 (edited) This Return Int(_WinAPI_GetStockObject(5)) is wrong. Don't use Int(), it doesn't work that way. This Func WM_CTLCOLORSTATIC($wParam, $lParam) is wrong if you expect these params to be the actual wParam and lParam. GuiRegisterMsg functions have 4 parameters, you can declare less and/or name them whatever you wish, but it won't change the fact that 1st parameter always is hWnd, 2nd is Msg, 3rd is wParam and 4th is lParam. So in your code you have declared window handle and message code as $wParam and $lParam. With these out of the picture, I'm afraid it still won't work with modern GUI themes. At least it didn't work for me (all I got was black rectangle). If you're positive that C++ example of yours does work, post whole of it, maybe there's more to it than just that snippet. Other than that, you can switch the checkbox to use Classic theme: $btnCheckBox = GUICtrlCreateCheckbox('Checkbox', 100, 90, 100, 20) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle(-1), "wstr", " ", "wstr", " ") and the transparency will kick in. Edited March 22, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Greenhorn Posted March 22, 2008 Author Share Posted March 22, 2008 Thanx for that information, Siao, now it comes clear to me why the first parameter looks like a handle and the 2nd was the constant of WM_CTLCOLORBTN/WM_CTLCOLORSTATIC ... I explored it in msdn, and there were only to parameter given - the wParam and the lParam - and in the 'Petzold' was the same to read ... I will try your tip with uxtheme.dll ... Greetz Greenhorn Link to comment Share on other sites More sharing options...
Greenhorn Posted March 22, 2008 Author Share Posted March 22, 2008 The working C++ code is down below. Tested with Code::Blocks v8.0.2 . Hmmm, yesterday it worked with the returned LRESULT from the GetStockObject, but today it won't ... Today it works by returning SendMessage ... oO Maybe I was too tired yesterday ... expandcollapse popup#include <windows.h> LRESULT CALLBACK WindowProc (HWND, UINT, WPARAM, LPARAM); static TCHAR szClassName[] = "CS Kino"; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nCmdShow) { HWND hWnd; MSG nMsg; WNDCLASSEX WndClass; WndClass.style = CS_HREDRAW | CS_VREDRAW; WndClass.hInstance = hInstance; WndClass.lpfnWndProc = WindowProc; WndClass.cbSize = sizeof (WNDCLASSEX); WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION); WndClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); WndClass.lpszMenuName = NULL; WndClass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); WndClass.lpszClassName = szClassName; if (!RegisterClassEx (&WndClass)) return 0; hWnd = CreateWindow(szClassName, "CS Kino", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 544, 375, NULL, NULL, hInstance, NULL); ShowWindow (hWnd, nCmdShow); while (GetMessage (&nMsg, NULL, 0, 0)) { TranslateMessage(&nMsg); DispatchMessage(&nMsg); } return nMsg.wParam; } LRESULT CALLBACK WindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hCheckBox; switch (message) { case WM_CREATE : hCheckBox = CreateWindow(TEXT("BUTTON"), TEXT("Checkbox"), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 100, 100, 100, 20, hWnd,(HMENU) 1, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL); return 0; case WM_CTLCOLORSTATIC : HDC hDC = (HDC) wParam; SetBkMode(hDC, TRANSPARENT); // this doesn't work, you're right, Siao;=) //return (LRESULT) GetStockObject(NULL_BRUSH); // but this works ! return SendMessage(hWnd, message, lParam, wParam); case WM_DESTROY : PostQuitMessage (0); break; } return DefWindowProc (hWnd, message, wParam, lParam); } Link to comment Share on other sites More sharing options...
Greenhorn Posted March 22, 2008 Author Share Posted March 22, 2008 OK, in AutoIt: expandcollapse popup#include <GUIConstants.au3> #Include <WinAPI.au3> #include <Misc.au3> If Not IsDeclared('OPAQUE') Then Global Const $OPAQUE = 0 If Not IsDeclared('TRANSPARENT') Then Global Const $TRANSPARENT = 1 If Not IsDeclared('WHITE_BRUSH') Then Global Const $WHITE_BRUSH = 0 If Not IsDeclared('LTGRAY_BRUSH') Then Global Const $LTGRAY_BRUSH = 1 If Not IsDeclared('GRAY_BRUSH') Then Global Const $GRAY_BRUSH = 2 If Not IsDeclared('DKGRAY_BRUSH') Then Global Const $DKGRAY_BRUSH = 3 If Not IsDeclared('BLACK_BRUSH') Then Global Const $BLACK_BRUSH = 4 If Not IsDeclared('NULL_BRUSH') Then Global Const $NULL_BRUSH = 5 If Not IsDeclared('HOLLOW_BRUSH') Then Global Const $HOLLOW_BRUSH = 5 If Not IsDeclared('WHITE_PEN') Then Global Const $WHITE_PEN = 6 If Not IsDeclared('BLACK_PEN') Then Global Const $BLACK_PEN = 7 If Not IsDeclared('NULL_PEN') Then Global Const $NULL_PEN = 8 If Not IsDeclared('SYSTEM_FONT') Then Global Const $SYSTEM_FONT = 13 If Not IsDeclared('DEFAULT_PALETTE') Then Global Const $DEFAULT_PALETTE = 15 If Not IsDeclared('ANSI_FIXED_FONT') Then Global Const $ANSI_FIXED_FONT = 11 If Not IsDeclared('ANSI_VAR_FONT') Then Global Const $ANSI_VAR_FONT = 12 If Not IsDeclared('DEVICE_DEFAULT_FONT') Then Global Const $DEVICE_DEFAULT_FONT = 14 ;If Not IsDeclared('DEFAULT_GUI_FONT') Then Global Const $DEFAULT_GUI_FONT = 17 If Not IsDeclared('OEM_FIXED_FONT') Then Global Const $OEM_FIXED_FONT = 10 If Not IsDeclared('SYSTEM_FIXED_FONT') Then Global Const $SYSTEM_FIXED_FONT = 16 ;GUIRegisterMsg($WM_CTLCOLORSTATIC, 'WM_CTLCOLORSTATIC') GUIRegisterMsg($WM_CTLCOLORBTN, 'WM_CTLCOLORBTN') $hWndMain = GUICreate("My CheckBox Button with Transparency", 300, 200, _ -1, -1, _ $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x00ff00) $pic = GUICtrlCreatePic(@SystemDir & '\oobe\images\wpaback.jpg', 0, 0, 300, 200) GUICtrlSetState(-1, $GUI_DISABLE) ; this button should have a transparent background, but it hasn't ... $btnCheckBox = GUICtrlCreateCheckbox('Checkbox', 100, 90, 100, 20) $btnPushButton = GUICtrlCreateButton('PushButton', 110, 150, 80, 20) ; will we see the pic instead of green ... ? I don't think so ... :( GUISetState() While True Switch GUIGetMsg() Case -3 Exit EndSwitch WEnd ;======================================================================================== ; WM_CTLCOLORSTATIC($hDC, $hCtrl) ;======================================================================================== Func WM_CTLCOLORSTATIC($hWnd, $nMsg, $wParam, $lParam) #forceref $hWnd, $nMsg, $wParam, $lParam Local $hDC = $wParam ConsoleWrite('$hDC (wParam) = ' & $hDC & @CR) SetBkMode($hDC, 1) Return _SendMessage($hWnd, $nMsg, $wParam, $lParam) EndFunc ;======================================================================================== ; Func SetBkMode() ;======================================================================================== Func SetBkMode($hDC, $flag = 0) If $flag < 0 Or $flag > 1 Then Return SetError(1) DllCall('gdi32.dll', 'int', 'SetBkMode', _ 'hwnd', $hDC, _ ; handle to Decive Context 'int', $flag) ; $flag: 1 = TRANSPARENT, 0 = OPAQUE EndFunc DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle(-1), "wstr", " ", "wstr", " ") also works fine, but it's not shown the picture, it is visible the GUI background. Maybe I have to paint the background picture with the GDI functions ... !?!?? Greetz Greenhorn Link to comment Share on other sites More sharing options...
Siao Posted March 22, 2008 Share Posted March 22, 2008 Well, here's your example modified expandcollapse popup#include <GUIConstants.au3> #Include <WinAPI.au3> Global $OPAQUE = 0 Global $TRANSPARENT = 1 GUIRegisterMsg($WM_CTLCOLORSTATIC, 'WM_CTLCOLORSTATIC') ;~ GUIRegisterMsg($WM_CTLCOLORBTN, 'WM_CTLCOLORBTN') $hWndMain = GUICreate("My CheckBox Button with Transparency", 300, 200, _ -1, -1, _ $WS_OVERLAPPEDWINDOW) GUISetBkColor(0x00ff00) $pic = GUICtrlCreatePic(@SystemDir & '\oobe\images\wpaback.jpg', 0, 0, 300, 200) GUICtrlSetState(-1, $GUI_DISABLE) ; this button should have a transparent background, but it hasn't ... $btnCheckBox = GUICtrlCreateCheckbox('Checkbox', 100, 90, 100, 20) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle(-1), "wstr", " ", "wstr", " ") $btnPushButton = GUICtrlCreateButton('PushButton', 110, 150, 80, 20) ; will we see the pic instead of green ... ? I don't think so ... GUISetState() While True Switch GUIGetMsg() Case -3 Exit EndSwitch WEnd ;======================================================================================== ; WM_CTLCOLORSTATIC($hDC, $hCtrl) ;======================================================================================== Func WM_CTLCOLORSTATIC($hWnd, $Msg, $wParam, $lParam) ;#forceref $wParam, $lParam ;eh? Local $hDC = $wParam ConsoleWrite('$hDC (wParam) = ' & $hDC & @CR) SetBkMode($hDC, $TRANSPARENT) Return _WinAPI_GetStockObject(5) ; 5 = NULL_BRUSH/HOLLOW_BRUSH ; working C++ code. ;HDC hDC = (HDC) wParam ; ;SetBkMode((HDC)wParam, TRANSPARENT) ; ;Return (long)_WinAPI_GetStockObject('HOLLOW_BRUSH') ; EndFunc ;======================================================================================== ; Func SetBkMode() ;======================================================================================== Func SetBkMode($hDC, $flag = 0) If $flag < 0 Or $flag > 1 Then Return SetError(1) DllCall('gdi32.dll', 'int', 'SetBkMode', _ 'hwnd', $hDC, _ ; handle to Decive Context 'int', $flag) ; $flag: 1 = TRANSPARENT, 0 = OPAQUE EndFunc #cs #define WHITE_BRUSH 0 #define LTGRAY_BRUSH 1 #define GRAY_BRUSH 2 #define DKGRAY_BRUSH 3 #define BLACK_BRUSH 4 #define NULL_BRUSH 5 #define HOLLOW_BRUSH NULL_BRUSH #define WHITE_PEN 6 #define BLACK_PEN 7 #define NULL_PEN 8 #define SYSTEM_FONT 13 #define DEFAULT_PALETTE 15 #ce Downloading Code::Blocks atm... "be smart, drink your wine" Link to comment Share on other sites More sharing options...
Greenhorn Posted March 23, 2008 Author Share Posted March 23, 2008 (edited) Amazing !!! It works !This here$btnCheckBox = GUICtrlCreateCheckbox('Checkbox', 100, 90, 100, 20) DllCall("UxTheme.dll", "int", "SetWindowTheme", "hwnd", GUICtrlGetHandle(-1), "wstr", " ", "wstr", " ")oÝ÷ Ù©Ýjëh×6;======================================================================================== ; WM_CTLCOLORSTATIC($hWnd, $Msg, $wParam, $lParam) ;======================================================================================== Func WM_CTLCOLORSTATIC($hWnd, $Msg, $wParam, $lParam) Local $hDC = $wParam SetBkMode($hDC, $TRANSPARENT) Return _WinAPI_GetStockObject(5) ; 5 = NULL_BRUSH/HOLLOW_BRUSH EndFunc ;======================================================================================== ; Func SetBkMode() ;======================================================================================== Func SetBkMode($hDC, $flag = 0) If $flag < 0 Or $flag > 1 Then Return SetError(1) DllCall('gdi32.dll', 'int', 'SetBkMode', _ 'hwnd', $hDC, _ ; handle to Decive Context 'int', $flag) ; $flag: 1 = TRANSPARENT, 0 = OPAQUE EndFuncresults in thisThank you very much for your help to solve this problem, Siao !I take my hat off to you !But what does it do, I can not reconstruct how it works together ...GreetzGreenhornp.s. The new final release of Code::Blocks is available here: http://www.codeblocks.org/ Edited March 23, 2008 by Greenhorn Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now