Windows 10 Dark-Mode
Moderator: Moderatoren
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Windows 10 Dark-Mode
hi,
Ich gehöre ja zu denen die Nachts arbeiten und da ist das "weiss" doch sehr hell.
deshalb verwende ich auch den "Nachtmodus" aber langsam gefällt mir auch der Dark-Modus wie ihn auch Firefox übernimmt.
nun frage ich mich wie ich meine Xbase++ Apps auf Dark-Modus umstellen kann.
wenn es ein visual Style wäre müsste es ja automatisch passieren wenn ich die Konstanten verwende, oder
wenn ich nun die Farben meiner Apps ändere komme ich nicht an alle Sachen, z.b. Frame. ran ...
hat da jemand schon eine Lösung
Ich gehöre ja zu denen die Nachts arbeiten und da ist das "weiss" doch sehr hell.
deshalb verwende ich auch den "Nachtmodus" aber langsam gefällt mir auch der Dark-Modus wie ihn auch Firefox übernimmt.
nun frage ich mich wie ich meine Xbase++ Apps auf Dark-Modus umstellen kann.
wenn es ein visual Style wäre müsste es ja automatisch passieren wenn ich die Konstanten verwende, oder
wenn ich nun die Farben meiner Apps ändere komme ich nicht an alle Sachen, z.b. Frame. ran ...
hat da jemand schon eine Lösung
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Windows 10 Dark-Mode
hi,
Ich habe mal angefangen eine App für den Darkmode Style vorzubereiten um zu testen an welchen Stellen man mit Farbe nicht weiter kommt.
bei XbParts wie XbpPushbutton() hilft das nun nicht weil o.g. Win32 Beschränkung eintritt. Dagegen hilft nur Owner Draw. damit fallen alle Common Dialog raus, wie auch die Msgbox(), da man dort kein Owner Draw machen kann.
ich habe nun folgende Erweiterungen :
Tabpage : Header mit Owner Draw aber ohne visual Effects
Pushbutton : Owner Draw mit visual Effect "Hover"
SLE : Frame in blau mit Owner Draw
XbpBrowse Header : Owner Draw statt visual Effect
so sieht es nun aus oder so
ich bin mir nicht sicher welches Design mit den SLE mir besser gefällt.
mit vielen weissen SLE ist es mir zu hell und das grau ...
p.s. mit dieses kleine Tool kann man schnell hell/dunkel umschalten https://www.wintools.info/index.php/easy-dark-mode
Ich habe mal angefangen eine App für den Darkmode Style vorzubereiten um zu testen an welchen Stellen man mit Farbe nicht weiter kommt.
im Optimalen Fall würde man im MAIN Dialog die gewünschten Presentation-Parameter und alle folgenden Controls erben die. eigene Farben gehen aber nur wenn kein Visual Style dazwischen funkt, also beiWin32 - Unter Windows können die Systemfarben für xxx nicht durch Presentation-Parameter geändert werden.
Code: Alles auswählen
o:useVisualStyle := .F.
ich habe nun folgende Erweiterungen :
Tabpage : Header mit Owner Draw aber ohne visual Effects
Pushbutton : Owner Draw mit visual Effect "Hover"
SLE : Frame in blau mit Owner Draw
XbpBrowse Header : Owner Draw statt visual Effect
so sieht es nun aus oder so
ich bin mir nicht sicher welches Design mit den SLE mir besser gefällt.
mit vielen weissen SLE ist es mir zu hell und das grau ...
p.s. mit dieses kleine Tool kann man schnell hell/dunkel umschalten https://www.wintools.info/index.php/easy-dark-mode
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Windows 10 Dark-Mode
und weiter geht es mit Darkmode.
die Farbe von Scrollbar kann man wohl nicht ändern
auch bei meinen DXE Controls lief nicht gleich alles im Darkmode
DXE_STATBAR() mit Owner Draw des "Panel". die "Bevel" (Trenner) sind immer noch hell und nur die "internen" reagieren auf Farbe ...
DXE_TOOLBAR() & DXE_REBAR() da gibt es kein Owner Draw. Es gibt aber Customdraw ( nicht der Abklasch von XbpBrowse )
https://docs.microsoft.com/en-us/window ... ustom-draw
das gilt für die folgenden Controls
Ich habe zwar Customdraw im DXE_Listview() aber für den Darkmode müsste man noch einen Trick verwenden.
wie man sieht ist das Problem wenn das Browse nicht vollständig gefüllt ist. da kann Customdraw nichts malen ...
nun kann man ein Listview mit einem Hintergrundbild belegen
die Farbe von Scrollbar kann man wohl nicht ändern
auch bei meinen DXE Controls lief nicht gleich alles im Darkmode
DXE_STATBAR() mit Owner Draw des "Panel". die "Bevel" (Trenner) sind immer noch hell und nur die "internen" reagieren auf Farbe ...
DXE_TOOLBAR() & DXE_REBAR() da gibt es kein Owner Draw. Es gibt aber Customdraw ( nicht der Abklasch von XbpBrowse )
https://docs.microsoft.com/en-us/window ... ustom-draw
das gilt für die folgenden Controls
---Header controls
List-view controls
Rebar controls
Toolbar controls
Tooltip controls
Trackbar controls
Tree-view controls
Ich habe zwar Customdraw im DXE_Listview() aber für den Darkmode müsste man noch einen Trick verwenden.
wie man sieht ist das Problem wenn das Browse nicht vollständig gefüllt ist. da kann Customdraw nichts malen ...
nun kann man ein Listview mit einem Hintergrundbild belegen
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Windows 10 Dark-Mode
moin,
bei DXE_Statbar() habe ich raus bekommen warum nur die "internen" Panel auf Farbe reagierten.
da Farbe nur mit Owner Draw funktioniert muss
verwendet werden
hab jetzt auch Custom-Draw in DXE_Toolbar eingebaut und die Pres-Parameter aktiviert.
es verschwindet immer mehr Weiss
Blau hab zum testen genommen denn Schwarz könnte auch ein "falsches" Resultat sein.
-- todo
beim DCE_TabCtl() stimmt die Farbe des (aktiven) Tab-Header noch nicht.
im Listview hat der Header noch visual Style
und die CMD-ComboBox muss noch umgestellt werden.
btw. den Listbox Teil der Combo mache ich per Ownerdraw und was/wie mache ich es mit dem SLE Teil der Combobox
bei DXE_Statbar() habe ich raus bekommen warum nur die "internen" Panel auf Farbe reagierten.
da Farbe nur mit Owner Draw funktioniert muss
Code: Alles auswählen
nBevel := SBT_OWNERDRAW
Code: Alles auswählen
IF nBevel = SBT_OWNERDRAW .AND. ::DrawMode <> XBP_DRAW_NORMAL
es verschwindet immer mehr Weiss
Blau hab zum testen genommen denn Schwarz könnte auch ein "falsches" Resultat sein.
-- todo
beim DCE_TabCtl() stimmt die Farbe des (aktiven) Tab-Header noch nicht.
im Listview hat der Header noch visual Style
und die CMD-ComboBox muss noch umgestellt werden.
btw. den Listbox Teil der Combo mache ich per Ownerdraw und was/wie mache ich es mit dem SLE Teil der Combobox
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Windows 10 Dark-Mode
moin,
ich hatte ja das Owner Draw in DXE_TabCtl() eingebaut. jetzt wollte ich es verwenden
nun ging das mit den Farben aber die Caption stimmte nicht wenn man z.b. das Verzeichnis gewechselt hat.
laut Anweisung von Microsoft geht es ganz einfach ...
https://docs.microsoft.com/en-us/window ... cm-getitemnur dummerweise kommt da nichts ...
beim suchen nach Beispielen fand ich diesen Artikel
https://autohotkey.com/board/topic/1646 ... m-getitem/
ich sah was mit
hm ... das hab ich doch schon mal gesehen ...
JA gefunden : GETDESK.PRG
es ging darum die Position der Icons auf dem Desktop festzustellen.
Problem : man kann sich nicht in die aktuelle Instanz einklinken
Workaround : "virtuellen Speicher" als Kopie nutzen
ja das Problem hab ich nun behoben und nun das nächste
wie man sehen kann gibt esbei Ownerdraw einen Bereich der für weitere Tabs oder Buttons am rechten Rand.
wenn der nun nicht gefüllt ist sieht man wieder eine Menge Weiss
ich hatte ja das Owner Draw in DXE_TabCtl() eingebaut. jetzt wollte ich es verwenden
nun ging das mit den Farben aber die Caption stimmte nicht wenn man z.b. das Verzeichnis gewechselt hat.
laut Anweisung von Microsoft geht es ganz einfach ...
https://docs.microsoft.com/en-us/window ... cm-getitem
Code: Alles auswählen
LOCAL lRet
LOCAL oItem
LOCAL nSize := 200
LOCAL cText := SPACE(nSize)
oItem := TCITEM() :NEW()
oItem:mask := TCIF_TEXT
oItem:pszText := cText + CHR( 0 )
oItem:cchTextMax := LEN( cText ) + 1
lRet := @USER32:SendMessageA( ::hTabCtl, TCM_GETITEM, nitemID, oItem )
IF lRet > 0
cText := oItem:pszText
beim suchen nach Beispielen fand ich diesen Artikel
https://autohotkey.com/board/topic/1646 ... m-getitem/
ich sah was mit
Code: Alles auswählen
DllCall( "VirtualAllocEx" ...)
DllCall( "WriteProcessMemory" ... )
DllCall( "ReadProcessMemory" ... )
JA gefunden : GETDESK.PRG
es ging darum die Position der Icons auf dem Desktop festzustellen.
Problem : man kann sich nicht in die aktuelle Instanz einklinken
Workaround : "virtuellen Speicher" als Kopie nutzen
Code: Alles auswählen
@User32:GetWindowThreadProcessId(::hTabCtl,@processId)
process := @Kernel32:OpenProcess(procFlags, .F. , processId)
GlobalBuffer := @Kernel32:VirtualAllocEx(process, NULL, nSize, MemFlags, PAGE_READWRITE)
oItem := TCITEM() :NEW()
oItem:mask := TCIF_TEXT
oItem:pszText := GlobalBuffer // <- virtueller Speicher
oItem:cchTextMax := nSize
pSizeString := oItem:_sizeof_()
GlobalStruct := @Kernel32:VirtualAllocEx(process, NULL, pSizeString, MemFlags, PAGE_READWRITE)
@Kernel32:WriteProcessMemory(process, GlobalStruct, @oItem , pSizeString, NULL)
@Kernel32:WriteProcessMemory(process, GlobalBuffer, @oItem , pSizeString, NULL)
// jetzt "lesen"
lRet := @USER32:SendMessageA( ::hTabCtl, TCM_GETITEM, nitemID , oItem )
cBuffer := SPACE(nSize)+CHR(0)
@Kernel32:ReadProcessMemory(process, GlobalBuffer, @cBuffer, pSizeString, NULL)
wie man sehen kann gibt esbei Ownerdraw einen Bereich der für weitere Tabs oder Buttons am rechten Rand.
wenn der nun nicht gefüllt ist sieht man wieder eine Menge Weiss
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Windows 10 Dark-Mode
moin,
ich habe eine ganze Zeit lang an der TAB Area getüftelt und die Lösung war ganz einfach
wenn ich mit Listview Owner Draw fertig bin errechne ich den Platz von den Tabsdamit fülle ich dann den Bereich hinter den Tabs auf.
ein leichtes flackern ist vorhanden wenn sich ein Tab ändert aber eben nur dann.
so damit bin ich fast durch ... "nur" noch der Header des Listview ist noch weiss.
nun stellte ich leider fest das es kaumr keine Methoden für den Zugriff auf den Listview-Header gibt
das einzige was der Listview Wrapper von Pablo bietet ist
also nur ein Handle zur HDITEM Structure.
ich konnte zwar die Zeile, per Ownerdraw, malen aber beim nächsten klick ... war alles wieder weiss
---
nach langen Recherchen stellte ich heraus das der Listview-Header ein "WC_HEADER" Control ist
man könnte es vergleichen mit einem Scrollbar von einem XbpDialog wo man "so" nicht einfach ran kommt.
die Lösung heisst SubClass mit ot4xb ... was eine längere Geschichte wurde ...
ich habe eine ganze Zeit lang an der TAB Area getüftelt und die Lösung war ganz einfach
wenn ich mit Listview Owner Draw fertig bin errechne ich den Platz von den Tabs
Code: Alles auswählen
FOR i := 1 TO iMax
aItemRect := ::GetItemRect(i-1)
nWide += (aItemRect[3]-aItemRect[1])
nWide += 1
NEXT
aRect[1] := nWide
aRect[2] := 0
aRect[3] := aSize[1]
aRect[4] := 64
ein leichtes flackern ist vorhanden wenn sich ein Tab ändert aber eben nur dann.
so damit bin ich fast durch ... "nur" noch der Header des Listview ist noch weiss.
nun stellte ich leider fest das es kaumr keine Methoden für den Zugriff auf den Listview-Header gibt
das einzige was der Listview Wrapper von Pablo bietet ist
Code: Alles auswählen
pHead := ::lv_GetHeader()
ich konnte zwar die Zeile, per Ownerdraw, malen aber beim nächsten klick ... war alles wieder weiss
---
nach langen Recherchen stellte ich heraus das der Listview-Header ein "WC_HEADER" Control ist
man könnte es vergleichen mit einem Scrollbar von einem XbpDialog wo man "so" nicht einfach ran kommt.
die Lösung heisst SubClass mit ot4xb ... was eine längere Geschichte wurde ...
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Windows 10 Dark-Mode
moin,
SubClass mittels ot4xb war klar aber wie löse ich ein Owner Draw des Listview Header aus ?
es kam nichts an ... ja bei Listview hab ich Ownerdraw / Customdraw aktiviert.
also fehlt mir hier noch noch die "Aktivierung" des Owner Draw vom "WC_HEADER" Control.
üblicherweise gibt es eine Konstante wie LVS_OWNERDRAWFIXED für Listview.
unter "WC_HEADER" hab ich nun HDF_OWNERDRAW gefunden ... aber der 3th Buchstabe ist ein "F" und kein "N"
ein "N" steht für Notify Event. diese würde man abfangen und darauf reagieren z.b. per EVAL(Codebock)
ein "F" steht hier nun für Format ... damit bestückt man die FMT Member einer Structure.
---
das einzige was der Listview Wrapper von Pablo bietet ist
also nur ein Handle zu einer Structure.
ich hatte es dann über die HDITEM Structure versucht.
https://docs.microsoft.com/en-us/window ... -_hd_itema
das "lesen/schreiben" der Structure ist kein Problem aber "wann" soll das passieren wenn man keinen Event hat ...
es funktionierte z.b. wenn dem man auf den Header klickt und einen Event auslöst den man dann zum "malen" nutzen kann. Nein ... das lief nicht richtig ... aber wo solle ich die Konstante HDF_OWNERDRAW sonst verwenden ...
---
nun gibt es auch weitere HDF_* Konstanten wie für die "Sortier-Pfeile" und deren Ausrichtung.
das ganze geht an die LVCOLUMN() Structure ... hm ...
wir sind der Lösung schon ganz nahe ... wer hat eine Idee
die Lösung gibt es in der nächsten Msg
SubClass mittels ot4xb war klar aber wie löse ich ein Owner Draw des Listview Header aus ?
Code: Alles auswählen
ot4xb_subclasswindow( ::hLv , MyHeadHandler() :New( self ), NIL,"Head_wndproc" )
Code: Alles auswählen
INLINE METHOD Head_wndproc(hWnd,nMsg,wp,lp,ctx)
LOCAL rc := {0,0,0,0}
Ondummy("Head_wndproc",TIME())
IF nMsg == WM_DRAWITEM
Ondummy("WM_DRAWITEM",TIME())
::Head_DrawItem(wp,lp,hWnd)
üblicherweise gibt es eine Konstante wie LVS_OWNERDRAWFIXED für Listview.
unter "WC_HEADER" hab ich nun HDF_OWNERDRAW gefunden ... aber der 3th Buchstabe ist ein "F" und kein "N"
ein "N" steht für Notify Event. diese würde man abfangen und darauf reagieren z.b. per EVAL(Codebock)
ein "F" steht hier nun für Format ... damit bestückt man die FMT Member einer Structure.
---
das einzige was der Listview Wrapper von Pablo bietet ist
Code: Alles auswählen
pHead := ::lv_GetHeader()
ich hatte es dann über die HDITEM Structure versucht.
https://docs.microsoft.com/en-us/window ... -_hd_itema
Code: Alles auswählen
oHDITEM := HDITEM():New()
oHDITEM:fmt := HDF_OWNERDRAW
oHDITEM:mask := HDI_TEXT
oHDITEM:pszText := cBuf
oHDITEM:cchTextMax := LEN(cBuf)
es funktionierte z.b. wenn dem man auf den Header klickt und einen Event auslöst den man dann zum "malen" nutzen kann. Nein ... das lief nicht richtig ... aber wo solle ich die Konstante HDF_OWNERDRAW sonst verwenden ...
---
nun gibt es auch weitere HDF_* Konstanten wie für die "Sortier-Pfeile" und deren Ausrichtung.
Code: Alles auswählen
IF Alignment = LVCFMT_LEFT
oLVCol2:fmt := nor(oLVCol2:fmt,HDF_LEFT ,HDF_BITMAP_ON_RIGHT )
ELSE
oLVCol2:fmt := nor(oLVCol2:fmt,HDF_RIGHT,HDF_BITMAP )
ENDIF
IF ::SortOrder == LVS_SORTASCENDING
oLVCol2:fmt := nOr(oLVCol2:fmt,HDF_SORTUP ) // this make the Icon !
ELSE
oLVCol2:fmt := nOr(oLVCol2:fmt,HDF_SORTDOWN) // this make the Icon !
ENDIF
wir sind der Lösung schon ganz nahe ... wer hat eine Idee
die Lösung gibt es in der nächsten Msg
gruss by OHR
Jimmy
Jimmy
- AUGE_OHR
- Marvin
- Beiträge: 12906
- Registriert: Do, 16. Mär 2006 7:55
- Wohnort: Hamburg
- Hat sich bedankt: 19 Mal
- Danksagung erhalten: 45 Mal
Re: Windows 10 Dark-Mode
moin,
der vorherige Code stammt aus der Aktion von einem klick auf den Listview Header.
damit wählt man eine Column aus aber dort wirkt ein setzten der HDF_OWNERDRAW Konstante nicht
also habe ich weiter nach HDF_OWNERDRAW gesucht und irgendwann ein "komisches" Beispiel gefunden ...
aber der Weg funktionierte
das "komische" war das die HDF_OWNERDRAW Konstante mit einer LVCOLUMN() Strukture verwenden wurde wo sonst nur LVCFMT_* Konstanten standen. das man die kombinieren kann war mir nicht klar aber es funktioniert
nach anlegen jeder Column und vor dem Insert jeder Column muss man die Konstante HDF_OWNERDRAW einsetzten dann bekommt man beim SubClass auch die WM_DRAWITEM Message
es fehlen noch die up/down Icons ... hm ... welche nimmt man da ...
ja man könnte mit WingDings etc. was machen ... aber noch einen Font nur für 1 Zeichen ...
also hab ich nun Windows System Icon genommen
wie man an solche System Icon kommt siehe hier
damit hätte ich es, bis auf die Scrollbar, geschafft das man die Farben der Controls verändern kann.
jetzt fehlen nur noch die "richtigen" Farben denn der Windows 10 Darkmode ist mehr als nur Schwarz
der vorherige Code stammt aus der Aktion von einem klick auf den Listview Header.
damit wählt man eine Column aus aber dort wirkt ein setzten der HDF_OWNERDRAW Konstante nicht
also habe ich weiter nach HDF_OWNERDRAW gesucht und irgendwann ein "komisches" Beispiel gefunden ...
aber der Weg funktionierte
das "komische" war das die HDF_OWNERDRAW Konstante mit einer LVCOLUMN() Strukture verwenden wurde wo sonst nur LVCFMT_* Konstanten standen. das man die kombinieren kann war mir nicht klar aber es funktioniert
Code: Alles auswählen
METHOD DXE_ArrayView:InitTheListView()
...
// add Ownerdraw
::oLVCol:fmt := nOr(::oLVCol:fmt, HDF_OWNERDRAW)
// insert Column now
::lv_InsertColumn(n-1,::oLVCol)
NEXT
IF !EMPTY(::lv_GetHeader())
// switch Theme OFF for Ownerdraw
@UxTheme:SetWindowTheme(::lv_GetHeader(),CHR(0),CHR(0))
// Subclass
ot4xb_subclasswindow(::hLv,MyHeadHandler():New(self),NIL,"Head_wndproc")
ENDIF
es fehlen noch die up/down Icons ... hm ... welche nimmt man da ...
ja man könnte mit WingDings etc. was machen ... aber noch einen Font nur für 1 Zeichen ...
also hab ich nun Windows System Icon genommen
Code: Alles auswählen
::IcoUp := DXE_Icon() :new() :create()
::IcoUp:load( WinDir+"\System32\NetShell.dll", 2301,16,16 )
::IcoDn := DXE_Icon() :new() :create()
::IcoDn:load( WinDir+"\System32\NetShell.dll", 2300,16,16 )
Code: Alles auswählen
https://www.xbaseforum.de/viewtopic.php?f=16&t=8808&p=125442
jetzt fehlen nur noch die "richtigen" Farben denn der Windows 10 Darkmode ist mehr als nur Schwarz
gruss by OHR
Jimmy
Jimmy