안녕하세요.
http://cbuilder.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_qna&no=39765
이 글처럼 TMainMenu에 ImageList를 사용하는 경우 핫키가 표시 안되는 버그가 있던데요.
검색해 보다보니까.
해결책을 비슷한 것을 찾은거 같은데요.
http://qc.borland.com/wc/qcmain.aspx?d=733
http://buglist.jrsoftware.org/generated/entry0677.htm
설명에 보니까.
기존 VLC code중에서 Menu.pas를 수정하라는 것이 더군요.
링크의 Workaround 1: 은 대충 알겠는데,
Workaround 2: 는 뭔 말인지 잘 모르겠거군요.
아무튼, 기존 VCL 소스가 있는
C:\Program Files\Borland\CBuilder6\Source\vcl
이곳에서 menu.pas 만 수정하면 자동으로 다시 컴파일 하나요?
제가 이전에 올리 테스트 프로그램을 다시 컴파일해도 적용이 안되는거 같은데요.
vcl 소스파일 수정했을때, 이것을 어떻게 다시 컴파일하여서 내 프로젝트에 적용을 시킬 수가 있나요?
수고하세요!
--------------------------------
Description
Reported by Marc Durdin; checked by Jordan Russell
In Windows 2000 and Delphi 5.0/5.01, accelerators on an OwnerDraw TMainMenu are not visible even when the Display.cpl/Effects/Hide keyboard navigation flag is off. This is due to D501 supporting the ODS_NOACCEL itemState flag in WM_DRAWITEM.
Reproducible:
Yes.
Instructions:
Create any application with a TMainmenu under Windows 2000, and ensure that the flag in the Display Control Panel/Effects titled "Hide keyboard navigation indicators until I use the Alt key" is OFF. The accerator underscores will never display.
Cause:
Bug in MS Windows. Only appears to be a problem with owner-drawn menus (all Delphi's menus are owner-drawn). Windows sets ODS_NOACCEL in WM_DRAWITEM even when the Control Panel option is off.
OS Version:
Windows 2000, Windows 2000 SP1, Windows 2000 SP2, Windows XP?
Solution / workaround
Workaround 1:
(Modifies VCL code -- also inefficient, but less work for integration into applications)
Modify, in 2 locations in menus.pas, the following code to TMenuItem.AdvancedDrawItem (approx lines 1200, 1400):
if Win2K and (odNoAccel in State) then
DrawStyle := DrawStyle or DT_HIDEPREFIX;
to:
var FAlwaysDrawUnderline: BOOL; {in variable declarations, approx line 1025}
if SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, @FAlwaysDrawUnderline, 0) then
if not FAlwaysDrawUnderline then
if Win2K and (odNoAccel in State) then
DrawStyle := DrawStyle or DT_HIDEPREFIX;
Workaround 2:
(Recommended -- more efficient and doesn't modify the VCL code)
Include the following code in the form with the MainMenu. This turns off the ODS_NOACCEL flag before the menu is drawn, if appropriate. If you want to ensure that the application updates its settings when the Control Panel option is changed, you can either (1) set FWndProcInit:=False in an Application.OnMessage event procedure when WM_SETTINGCHANGE is received, or (2) set FWndProcInit:=False in an Application.OnActivate event procedure.
const
SPI_GETKEYBOARDCUES = $100A;
var
FAlwaysDrawUnderline: BOOL = False;
FWndProcInit: Boolean = False;
procedure TfrmTike.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_DRAWITEM:
begin
if not FWndProcInit then
begin
SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, @FAlwaysDrawUnderline, 0);
FWndProcInit := True;
end;
if FAlwaysDrawUnderline then
with PDrawItemStruct(Message.lParam)^ do
if (CtlType = ODT_MENU) and Assigned(Menu) then
itemState := itemState and $FEFF;
end;
end;
inherited;
end;
-------------------------------------------------