VCL 수정 후 컴파일은 델파이에서만 되는 것으로 알고 있습니다. 빌더에선 VCL소스는 말 그대로 참조용일 뿐입니다.
그렇다고 해결책이 없어보이진 않구요, TMainMenu의 WndProc를 가로채는 방법을 쓰시면 될 듯 합니다.
저도 올려놓으신 소스를 자세히 보지는 않았지만 보통 WndProc 부분을 수정해야 하는 경우 메시지 일부만을 가로채거나 혹은 WndProc를 통째로 갈아치우는 방법을 쓰시면 됩니다.
볼레롱 님이 쓰신 글 :
: 안녕하세요.
:
:
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;
:
:
: -------------------------------------------------