Ecco un altro modo di riprodurre il problema:
- Complete passaggi da 1 a 4 come nella domanda (compreso il rilascio di una TwilightColorMap).
- Aggiungere un pulsante al modulo con il codice
Perform(WM_SETTINGCHANGE, 0, 0);
nel relativo gestore di clic.
- Eseguire l'applicazione e premere il pulsante.
Così ora sappiamo che una trasmissione WM_SETTINGCHANGE
potrebbe essere la causa del problema, potremmo chiederci se il lancio di IE produce lo stesso:
type
TForm1 = class(TForm)
..
protected
procedure WMSettingChange(var Message: TWMSettingChange);
message WM_SETTINGCHANGE;
..
procedure TForm1.WMSettingChange(var Message: TWMSettingChange);
begin
Memo1.Lines.Add(IntToHex(Message.Flag, 4) + ', ' + Message.Section);
inherited;
end;
Dopo corriamo la nostra applicazione e poi lanciare IE, alcuni secondi dopo il sotto compare nel memo:
0000, Software \ Microsoft \ Internet Explorer \ SearchScopes
Non ho idea di cosa IE debba dire al nostro modulo (e a tutte le altre finestre di primo livello) ad ogni avvio, e non so se lo sta facendo su tutte le finestre di Windows o solo sul mio e sul mio , ma evidentemente il ActionMainMenuBar
non è in grado di gestirlo.
Un controllo di vittoria (il modulo), ricevendo un WM_WININICHANGE
, esegue un CM_WININICHANGE
e al momento del ricevimento trasmette lo stesso a tutti i suoi controlli. Il sotto è come viene gestito dalla barra dei menu:
procedure TCustomActionMainMenuBar.CMWininichange(var Message: TWMWinIniChange);
begin
inherited;
RequestAlign;
Font.Assign(Screen.MenuFont);
end;
Pensando che il tipo di carattere menu di sistema potrebbe essere stato modificato (il codice dovrebbe avere guardato per un 'WindowsThemeElement' o la sezione 'WindowMetrics' nel messaggio, ma comunque ..), viene riassegnato dall'aggiornato Screen.MenuFont
. Il problema è che non lo stavamo usando esattamente.
Inoltre, ColorMap risponde a CM_WININICHANGE
ripristinando i relativi colori chiamando il metodo UpdateColors
. Questo è ancora documented:
UpdateColors viene chiamato automaticamente quando un componente ActionBand riceve un messaggio CM_WININICHANGE.
Quindi la soluzione comporterebbe decidere cosa fare e ignorando sia il comportamento, ho cercato di commentare la soluzione qui di seguito per questo che credo che sarebbe la soluzione giusta:
type
// Derive your own ColorMap that would reset its own colors.
// This is an interposer for simplicity..
TTwilightColorMap = class(actncolormaps.TTwilightColorMap)
public
procedure UpdateColors; override;
published
property Color default clGreen;
property FontColor default clYellow;
property MenuColor default $4488FF;
// reintroduce as many property as necessary, probably all is necessary..
end;
TForm1 = class(TForm)
..
private
FSaveMenuFont: TFont; // will hold initial main menu bar's font settings
protected
procedure WMSettingChange(var Message: TWMSettingChange);
message WM_SETTINGCHANGE;
end;
..
procedure TForm1.FormCreate(Sender: TObject);
begin
FSaveMenuFont := TFont.Create;
FSaveMenuFont.Assign(ActionMainMenuBar1.Font);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FSaveMenuFont.Destroy;
end;
procedure TForm1.WMSettingChange(var Message: TWMSettingChange);
begin
inherited;
// The below are the *section*s that really changing system settings
// would notify that I'm aware of, there may be more...
if (Message.Section <> 'WindowsThemeElement')
or (Message.Section <> 'WindowMetrics') then
ActionMainMenuBar1.Font.Assign(FSaveMenuFont)
else
// Develop your logic here. The system menu font might really have been
// changed. You can get it from Screen.MenuFont. But then if we had been
// using the system font, the control already applies the change by default.
end;
procedure TTwilightColorMap.UpdateColors;
begin
inherited;
// Reset your colors, note that system colors might have been
// changed or not. If changed, they should be reflected in 'cl..' constants.
Color := clGreen;
FontColor := clYellow;
MenuColor := $4488FF;
end;
ouch, molto probabilmente un'impostazione del Registro di sistema ... prova a cercare il codice sorgente per Registry, vedi dove è l'implementazione "salva/carica" e fai una soluzione ... – ComputerSaysNo
Quando dici che ActionMainMenuBar "perde tutte le sue impostazioni 'ti riferisci a impostazioni di proprietà o immagini o gestori di eventi o qualcos'altro? –
Sta perdendo le impostazioni delle proprietà, in questo caso i colori definiti nella mappa colori e le impostazioni del carattere. – Phil