I thought it would be easy to change the statuswindow color.
mov status_hnd, rv(CreateWindowEx,0,"msctls_statusbar32","Some text", WS_CHILD or WS_VISIBLE,0,0,0,0,main_hwnd,0,0,0)
RGB 0,0,255
invoke SendMessage,status_hnd,SB_SETBKCOLOR,0,eax
Returns 4278190080 0xFF000000
It isn't because the color doesn't change
A status bar colour is set by the settings in your operating system, its not adjustable. You can code your own but its no fun.
A status bar colour is set by the settings in your operating system, its not adjustable. You can code your own but its no fun.
The SB_SETBKCOLOR message is good for what ?
https://social.msdn.microsoft.com/Forums/vstudio/en-US/73bf4ce9-e91b-4347-bb9b-91c3ad1116e8/setting-background-of-status-bar?forum=vcgeneral
No rocket science, it works fine on Win7-64 - source attached (if you don't have RichMasm, open the *.asc file in WordPad). And yes, this is an ordinary CreateStatusWindowW bar.
Quote from: clamicun on May 05, 2019, 05:13:47 AMThe SB_SETBKCOLOR message is good for what ?
It is good for setting the statusbar colour in case you have disabled "visual styles", "aero themes", whatever you want to call that crap. My method works also with Aero.
Beautiful, jj
Tryin to understand it
Disabling a Theme from statusbar is an option too.
EDIT: this wasn't tested yet ?
sUXT db "UxTheme.dll",0
sFunc db "SetWindowTheme",0
swNull dw 0
Wnd dd ?
INVOKE LoadLibraryA, ADDR sUXT
.if eax
INVOKE GetProcAddress, eax, ADDR sFunc
.if eax
push OFFSET swNull
push OFFSET swNull
push [Wnd]
call eax
.endif
.endif
To make it a bit easier.
ok. seems to be difficult to change the color of a "real" status bar-
Trying this one.
.if uMsg == WM_CREATE
INVOKE GetClientRect,main_hwnd,offset client
sub client.bottom,23
mov status_hnd, rv(CreateWindowEx,0,"Static","Some text", WS_CHILD or WS_VISIBLE,0,client.bottom,client.right,23,main_hwnd,0,0,0)
This looks like a status bar
How to change the background of this child window ?
It is set in your WNDCLASSEX for the window.
Hi clamicun,
Here is how to create a status bar and change the color :
.IF uMsg==WM_INITDIALOG
invoke CreateStatusWindow,WS_CHILD or WS_VISIBLE,\
ADDR sbtext,hWnd,IDW_STATBAR
mov hStatusBar,eax
RGB 200,210,50
invoke SendMessage,hStatusBar,SB_SETBKCOLOR,0,eax
Hi Erol,
As explained above, Windows ignores SB_SETBKCOLOR if an Aero resp "visual" theme is active.
In Reply #3 from fearless is a link
QuoteSo, disable theme for status bar (SetWindowTheme) and color it using SB_SETBKCOLOR.
Hi Jochen,
I tested the example on a Windows 7 64-bit system with the aero effect enabled. No any problem.
Quote from: Vortex on May 06, 2019, 03:19:39 AM
I tested the example on a Windows 7 64-bit system with the aero effect enabled. No any problem.
I don't think it will work with Visual Styles enabled and "all" applications use to have Visual Styles enabled:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="CompanyName.ProductName.YourApplication"
type="win32"
/>
<description>Your application description here.</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
It is possible to turn off Visual Styles on some controls by calling SetWindowTheme.
So this works with Visual Styles enabled (modified Vortex code, thank you):
include SetStatBarCol.inc
RGB MACRO red,green,blue
xor eax,eax
mov ah,blue
shl eax,8
mov ah,green
mov al,red
ENDM
DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD
IDW_STATBAR equ 1000
.data
DlgBox db 'DLGBOX',0
sbtext db 'Status bar',0
includelib \masm32\lib\UxTheme.lib
SetWindowTheme proto :HWND, :ptr, :ptr
.data
hStatusBar dd ?
nada db 0
.code
start:
invoke GetModuleHandle,0
invoke DialogBoxParam,eax,ADDR DlgBox,0,ADDR DlgProc,0
invoke ExitProcess,eax
DlgProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.IF uMsg==WM_INITDIALOG
invoke CreateStatusWindow,WS_CHILD or WS_VISIBLE,\
ADDR sbtext,hWnd,IDW_STATBAR
mov hStatusBar,eax
invoke SetWindowTheme, hStatusBar, offset nada, offset nada
RGB 255,0,0
invoke SendMessage,hStatusBar,SB_SETBKCOLOR,0,eax
.ELSEIF uMsg==WM_CLOSE
invoke EndDialog,hWnd,0
.ELSE
xor eax,eax
ret
.ENDIF
mov eax,1
ret
DlgProc ENDP
END start
Quote from: Vortex on May 06, 2019, 03:19:39 AM
Hi Jochen,
I tested the example on a Windows 7 64-bit system with the aero effect enabled. No any problem.
Hi Erol,
I just built your code and tested it, and strangely enough, it works with Aero enabled. This is weird, my SB_SETBKCOLOR message refuses to work with Aero (and it works fine with a non-Aero theme). Mysteries of Windows... :(
Mine is a window, yours is a dialog - could that make a difference?
compatibility section in manifest ?
EDIT: RGB macro
;#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
RGB MACRO r:REQ,g:REQ,b:REQ
EXITM %((r and 0ffh) or ((g and 0ffh) shl 8) or ((b and 0ffh) shl 16) )
ENDM
You nailed it, Timo :t
So the situation under Windows 7-64 is as follows (source & 2*exe attached):
- SB_SETBKCOLOR works always if no "visual" theme is activated
- if, however, an "Aero" or "visual" theme is active, then
- SB_SETBKCOLOR works if no manifest is present, i.e. common controls version 5.82 are being used (see statusbar text in the two attached executables)
- SB_SETBKCOLOR does not work if an XP manifest is being used (version 6.16 in the statusbar text).
In the last case, subclassing will still work, see the if 0 under .code in the source.
Unless Micros**t provides a credible excuse for this behaviour, I call it a Windows bug :P
P.S.: The manifest:<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<description>MasmBasic</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
/>
</dependentAssembly>
</dependency>
</assembly>
Compatibility section in Manifest has no influence.
Right. Exactly the same behaviour with this manifest (MS docs (https://docs.microsoft.com/en-us/windows/compatibility/application-executable-manifest)):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<description>MasmBasic</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates app support for Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!--The ID below indicates app support for Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!--The ID below indicates app support for Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
</application>
</compatibility>
</assembly>
And as soon as you take away the common controls version="6.0.0.0" stuff, the message starts working again. Subclassing works always, of course. It's a Windows bug, that's all :P
Owner Draw works too.
SendMessage(hStatus, SB_SETTEXT, SBT_OWNERDRAW, (LPARAM)"test");
...
void OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem)
{
if (lpDrawItem->CtlID== IDC_STATUS) {
FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, (HBRUSH)3);
TextOut(lpDrawItem->hDC, 4, 4, (char*)lpDrawItem->itemData, 4);
}
return;
}
Vortex,
Compiles and works with Windows 10 64b
.IF uMsg==WM_INITDIALOG
mov status_hnd,rv(CreateStatusWindow,WS_CHILD or WS_VISIBLE,"Some text",main_hwnd,status_ID)
RGB 200,210,50
invoke SendMessage,status_hnd,SB_SETBKCOLOR,0,eax
If I don't build a dialog but a "normal" window and use
.if uMsg == WM_CREATE
mov status_hnd,rv(CreateStatusWindow,WS_CHILD or WS_VISIBLE,"Some text",main_hwnd,status_ID)
RGB 200,210,50
invoke SendMessage,status_hnd,SB_SETBKCOLOR,0,eax
It doesn't work ???
jj,
"Mine is a window, yours is a dialog - could that make a difference?"
Exactly
jj,
trying to compile MapViewerWithRedStatusBar.asm I get an error
E:\masm32\examples\jjs_beispiel\MapViewerWithRedStatusBar.asm(1): Main line code
## MasmBasic GUI build ##
## deb: excluded WM_MOUSEMOVE, WM_NCHITTEST, WM_SETCURSOR, WM_GETICON, WM_NCMOUSEMOVE, WM_MOVING, WM_ENTERIDLE ##
## creating 3 controls ##
MapViewerWithRedStatusBar.asm: 62 lines, 1 passes, 233 ms, 0 warnings, 1 errors
Vortex,
this too is interessant.
If I don't use
invoke DialogBoxParam
but
Dialog "Status Bar...... and
CallModalDialog
it works as well, but the status window has a SIZEGRIP without including SBARS_SIZEGRIP in the style
Here the source.
;-----------------------------------
include \masm32\include\masm32rt.inc
IDW_STATBAR equ 1000
.data
sbtext db 'Status bar',0
.data?
hStatusBar dd ?
hInstance dd ?
.code
start:
invoke GetModuleHandle,0
mov hInstance,eax
call status_Testdialog
invoke ExitProcess,eax
;---------------------------------
status_Testdialog proc
Dialog "Status Bar...","Arial",12,WS_VISIBLE+DS_CENTER+WS_SYSMENU+WS_THICKFRAME,1,0,0,170,140,1024
DlgButton 'Cancel',WS_VISIBLE+BS_DEFPUSHBUTTON, 79,25,35,10,IDCANCEL
CallModalDialog hInstance,0,STATUS_TESTDIALOG,NULL
ret
status_Testdialog endp
;---------------------------------
STATUS_TESTDIALOG proc,hwnd,uMsg,wparam,lparam
mov ebx,uMsg
cmp ebx,WM_COMMAND
je wm_command
cmp ebx,WM_CLOSE
je wm_close
cmp ebx,WM_INITDIALOG
je wm_initdialog
jmp finish
wm_initdialog:
invoke CreateStatusWindow,WS_CHILD or WS_VISIBLE,ADDR sbtext,hwnd,IDW_STATBAR
mov hStatusBar,eax
RGB 200,210,50
invoke SendMessage,hStatusBar,SB_SETBKCOLOR,0,eax
jmp finish
wm_command:
cmp [wparam],IDCANCEL
je wm_close
finish:
xor eax,eax
ret
wm_close:
INVOKE EndDialog,hwnd,0
ret
ret
STATUS_TESTDIALOG endp
;================================
END start
Quote from: clamicun on May 06, 2019, 08:50:36 PM
trying to compile MapViewerWithRedStatusBar.asm I get an error
Which error? Assemblers produce typically something like "Tmp_File.asm(9) : Error A2210: Syntax error: bla"...
I also wonder why you see the "## deb: excluded ..." message, it appears only if you debug Windows messages.
for Vortex example to use OD: ...
invoke SendMessage,hStatusBar,SB_SETTEXT,SBT_OWNERDRAW,ADDR sbtext
.ELSEIF uMsg==WM_DRAWITEM
mov edi,lParam
.IF [edi].DRAWITEMSTRUCT.CtlID == IDW_STATBAR
invoke FillRect,[edi].DRAWITEMSTRUCT.hDC,ADDR [edi].DRAWITEMSTRUCT.rcItem,3
invoke TextOut,[edi].DRAWITEMSTRUCT.hDC,4,4,[edi].DRAWITEMSTRUCT.itemData,10
.ENDIF
...
Which error? Assemblers produce typically something like "Tmp_File.asm(9) : Error A2210: Syntax error: bla"...
What can I say
*** MasmBasic version 02.05.2019 ***
\masm32\MasmBasic\Res\MbGui.asm(3441) : Error A2164: Empty (null) string
repargA(85)[MasmBasic.inc]: Macro called from
uChr$(1)[MasmBasic.inc]: Macro called from
\masm32\MasmBasic\Res\MbGui.asm(3441): Included by
E:\masm32\examples\jjs_beispiel\MapViewerWithRedStatusBar.asm(1): Main line code
## MasmBasic GUI build ##
## deb: excluded WM_MOUSEMOVE, WM_NCHITTEST, WM_SETCURSOR, WM_GETICON, WM_NCMOUSEMOVE, WM_MOVING, WM_ENTERIDLE ##
## creating 3 controls ##
MapViewerWithRedStatusBar.asm: 62 lines, 1 passes, 236 ms, 0 warnings, 1 errors
_
Assembly Error
Drücken Sie eine beliebige Taste . . .
Or the asc.file
** Start E:\masm32\MasmBasic\Res\bldallRM.bat **
**** 32-bit assembly ****
*** Assemble, link and run MapViewerWithRedStatusBar ***
MapViewerWithRedStatusBar.rc (4): error RC2135 : file not found: \Masm32\MasmBasic\Res\Europe.dmi
MapViewerWithRedStatusBar.rc (5): error RC2135 : file not found: \Masm32\MasmBasic\Res\Europe.map
MapViewerWithRedStatusBar.rc (6): error RC2135 : file not found: \Masm32\MasmBasic\Res\MapsInMasmBasic.asc
*** Resource "MapViewerWithRedStatusBar.rc" could not be created ***
Thanks a lot, clamicun. The rc missing files message is easy to solve, download what's missing (http://download%20what's%20missing). The Error A2164 is weird, though; it works fine here. It could be an issue with the assembler. What are you using, UAsm64, the default for RichMasm? Which version?
I don't know what you are talking about but there are no differences in these respects between dialog and main window.
(https://www.dropbox.com/s/jd81mash4hfuz0r/visuallyNS.jpg?dl=1)(https://www.dropbox.com/s/03vfgpdgbhmakfb/visuallyS.jpg?dl=1)
Quote from: AW on May 07, 2019, 02:08:05 AM
I don't know what you are talking about but there are no differences in these respects between dialog and main window.
Correct. As discussed above, it's not the difference between window and dialog (there isn't any), but rather the use of common controls version 5.82 (pre-XP) and version 6.16+ (Win7 and after). The latter doesn't understand the SB_... message when visual themes are active. The old 5.82 works fine with "visual" themes (I hate this "visual" word, it's so meaningless; "Aero" made more sense).
Quote from: jj2007 on May 07, 2019, 02:22:59 AM
The latter doesn't understand the SB_... message when visual themes are active. The old 5.82 works fine with "visual" themes (I hate this "visual" word, it's so meaningless; "Aero" made more sense).
There is some confusion here. It understands the SB_... when we exclude the pertinent control out of the theme. This is what we have been talking about since long. I.e, we need to exclude the status bar.
Hi Jochen,
Probably, I was lucky as I first tried the status bar on a dialog box. Interesting case. My Windows 7 64-bit setup is a standard one. I can tell that the Aero theme is enabled as I can hit the Windows flag + TAB combination to view the superposition of application windows.
Hi clamicun,
I only tested the status bar on a dialog box. Let's see the results of the new tests.
for Vortex example to use OD: ...
invoke SendMessage,hStatusBar,SB_SETTEXT,SBT_OWNERDRAW,ADDR sbtext
.ELSEIF uMsg==WM_DRAWITEM
mov edi,lParam
.IF [edi].DRAWITEMSTRUCT.CtlID == IDW_STATBAR
invoke FillRect,[edi].DRAWITEMSTRUCT.hDC,ADDR [edi].DRAWITEMSTRUCT.rcItem,3
invoke TextOut,[edi].DRAWITEMSTRUCT.hDC,4,4,[edi].DRAWITEMSTRUCT.itemData,10
.ENDIF
timoVJL,
yes, it works, the status bar is colored, but the text is black/white.
So actually it isn't good for anything, but I am learning a lot.
vortex,
I tested the status bar on a dialog box. Let's see the results of the new tests.
It works with a window as well
windows 10 64b
ADDR [edi].DRAWITEMSTRUCT.rcItem,3
This I don't understand. 3 is a color/brush on fillrect , but if I use anything but a number (e.g. 1 = black) it doesn' work.
Why not ?
RGB 0,0,255
ADDR [edi].DRAWITEMSTRUCT.rcItem,eax
Same with the lenght:
[edi].DRAWITEMSTRUCT.itemData,60 ; works but a var doesn't.
mov eax,len(addr textstring)
[edi].DRAWITEMSTRUCT.itemData,eax
Quote from: AW on May 07, 2019, 02:35:33 AMI.e, we need to exclude the status bar.
My analysis is correct: A statusbar that was created by a program with an XP manifest doesn't handle the SB_SETBKCOLOR message correctly when a "visual" theme is active.
But your workaround for this Windows bug is also correct - and I confess I had not understood previously that one can "exclude" a
single control using SetWindowTheme. This works fine:
Dll "UxTheme"
Declare void SetWindowTheme, 3
SetWindowTheme(hSbar, 0, wChr$(0))
invoke SendMessageW, hSbar, SB_SETBKCOLOR, 0, LiteRed
That 3 was just a color index.
With a real brush .IF uMsg==WM_INITDIALOG
...
invoke CreateSolidBrush,RGB(200,210,50)
mov hBkBrush, eax
invoke SendMessage,hStatusBar,SB_SETTEXT,SBT_OWNERDRAW,ADDR sbtext
.ELSEIF uMsg==WM_DRAWITEM
mov edi,lParam
.IF [edi].DRAWITEMSTRUCT.CtlID == IDW_STATBAR
invoke FillRect,[edi].DRAWITEMSTRUCT.hDC,ADDR [edi].DRAWITEMSTRUCT.rcItem,hBkBrush
invoke SetBkMode,[edi].DRAWITEMSTRUCT.hDC,1 ;TRANSPARENT
invoke TextOut,[edi].DRAWITEMSTRUCT.hDC,4,5,[edi].DRAWITEMSTRUCT.itemData,10
.ENDIF
Pascal style strings, first byte is a lenght of string...
sbLText db 10,'Status bar',0
...
invoke SetBkMode,[edi].DRAWITEMSTRUCT.hDC,1 ;TRANSPARENT
mov eax, [edi].DRAWITEMSTRUCT.itemData
movsx ecx, BYTE PTR [eax]
inc eax
invoke TextOut,[edi].DRAWITEMSTRUCT.hDC,4,5,eax,ecx
EDIT: In C toovoid OnDrawItem(HWND hwnd, const DRAWITEMSTRUCT * lpDrawItem)
{
if (lpDrawItem->CtlID == IDC_STATUS) {
FillRect(lpDrawItem->hDC, &lpDrawItem->rcItem, hBkBrush);
SetBkMode(lpDrawItem->hDC, TRANSPARENT);
char *p = (char*)lpDrawItem->itemData;
TextOut(lpDrawItem->hDC, 4, 5, p, *(p++));
}
return;
}
Timo VJL,
Absolutely wonderful. Works perfectly with dialogs and windows.
"Problem" solved. Many Thanks
One thing I don't understand in my example Status_win_color.
If I don't include the manifest.xml it works, but the status window has a "Grip".
Thanks again
clamicun
In normal window you have to handle WM_SIZE and send / relay a WM_SIZE to statusbar.
I wonder why you want to resort to complicated solutions. José's suggestion works just fine...
SetWindowTheme(hSbar, 0, wChr$(0))
invoke SendMessageW, hSbar, SB_SETBKCOLOR, 0, Rgb(whatever)
Case you talk to me. It's the only solution which works on my computer windows 10 Home 64b
> One thing I don't understand in my example Status_win_color.
If I don't include the manifest.xml it works, but the status window has a "Grip".
Without the manifest you get the old Windows interface.
Quote from: clamicun on May 08, 2019, 09:06:42 AM
Case you talk to me. It's the only solution which works on my computer windows 10 Home 64b
I also have a Windows 10 Home 64 machine, and the SB_SETBKCOLOR works fine there, provided you use SetWindowTheme as shown above.
Interesting btw that common controls are stuck at version 6.16 since Windows XP. There is (was?) apparently a version 7.0 that shipped with Office 2016, but they're crashing Excel (https://answers.microsoft.com/en-us/msoffice/forum/all/common-controls-70-are-here-and-theyre-crashing/414b12c6-5752-424e-b515-fac42ee0ab35) :badgrin:
If we include the WS_THICKFRAME style the window will have a grip.
jj,
a couple of days ago you wrote:
"Mysteries of Windows..."
Quote from: AW on May 08, 2019, 07:36:25 PM
If we include the WS_THICKFRAME style the window will have a grip.
If the parent window have that WS_THICKFRAME style.
Quote from: TimoVJL on May 08, 2019, 08:51:18 PM
If the parent window have that WS_THICKFRAME style.
I am sure it has the WS_THICKFRAME style, don't you?
Statusbar have 50000000h, only WS_CHILD or WS_VISIBLE
, so parent window rules, and dialog don't usually don't have WS_THICKFRAME and no grip.
Quote from: TimoVJL on May 08, 2019, 09:11:18 PM
Statusbar have 50000000h, only WS_CHILD or WS_VISIBLE
, so parent window rules, and dialog don't usually don't have WS_THICKFRAME and no grip.
There is no grip in the dialog I am talking about the example where a window was created with the WS_OVERLAPPEDWINDOW style. This where all complaints are coming from.
(https://www.dropbox.com/s/b89muszsnmj6b3m/confusing.jpg?dl=1)
Quote from: clamicun on May 08, 2019, 07:56:45 PM
jj,
a couple of days ago you wrote:
"Mysteries of Windows..."
Yes, and we (José and I) solved them. Anyway, SB_SETBKCOLOR doesn't work as it should, so that's commonly called a
bug.