C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[758] [Win32] 시스템 메뉴 내맘대로 2 - 작업표시줄 메뉴 바꾸기
장성호 [nasilso] 8967 읽음    2008-03-18 14:48
작업표시줄에 메뉴를 내맘대로 조정하려면..
Applicaiton->Handle로  GetSystemMenu 해서 .. 처리해야 한다.


그렇게 하지 않고 좀더 쉽게 ..
TPopupMenu를  SystemMenu대신 띄우도록 하는 방법입니다.

원리는..

1. Application을 SubClassing해서요
2. TrackBar에 메뉴를 띄우라는 메세지를 잡어서 ...
3. TPopupmenu를 해당 위치에 띄우는것입니다.


컴포넌트

이것을 누가 컴포넌트로 이미 만들어 뒀더군요
http://delphi.about.com/od/vclwriteenhance/a/ttaskbarmenu.htm


그런데 저걸 굳이 컴포넌트화 까지 할 필요가 있나 싶어서
그냥 C++Builder로 변환해 보았습니다.

const int WM_TASKBAR_MENU = 0x0313; // magic!
void *oldWndProc;
void *newWndProc;

void __fastcall TForm1::FormCreate(TObject *Sender)
{
     oldWndProc =(void *) GetWindowLong(Application->Handle, GWL_WNDPROC) ;
     newWndProc = (void *)MakeObjectInstance(AppMessage) ;
     SetWindowLong(Application->Handle, GWL_WNDPROC, LPARAM(newWndProc)) ;
}
void __fastcall TForm1::AppMessage(TMessage &Msg)
{
    if(Msg.Msg==WM_TASKBAR_MENU)
    {
        PostMessage(Application->Handle,WM_POPUP_MENU,0,0);
        return;
    }
    else if(Msg.Msg==WM_POPUP_MENU)
    {
        TPoint pt;
        GetCursorPos(&pt);
        PopupMenu1->Popup(pt.x,pt.y);
    }
    else
    {
        Msg.Result = CallWindowProc((FARPROC)oldWndProc, Application->Handle, Msg.Msg, Msg.WParam, Msg.LParam) ;
    }
}


[TTaskBarMenu 컴포넌트 소스]
참조하세요


unit TaskBarMenu;

interface

uses
   SysUtils, Classes, Menus, Messages, Windows, Forms, Controls;

type
   TTaskBarMenu = class(TPopupMenu)
   private
     hookHandle : THandle;
     oldWndProc: Pointer;
     newWndProc: Pointer;
   protected
     procedure Hook;
     procedure UnHook;
     procedure AppWndProc(var Msg: TMessage) ;
   public
     constructor Create(AOwner: TComponent) ; override;
     destructor Destroy; override;
   end;

procedure Register;

implementation

const
   WM_TASKBAR_MENU = $0313; // magic!

   WM_POPUP_MENU = WM_USER + 1; //custom message

var
   thisOnce : TTaskBarMenu = nil;


procedure Register;
begin
   RegisterComponents('delphi.about.com', [TTaskBarMenu]) ;
end;

{ TTaskBarMenu }

procedure TTaskBarMenu.AppWndProc(var Msg: TMessage) ;
begin
   case Msg.Msg of
     WM_TASKBAR_MENU: PostMessage(hookHandle, WM_POPUP_MENU, 0, 0) ;
     WM_POPUP_MENU: Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y) ;
   else
     Msg.Result := CallWindowProc(oldWndProc, hookHandle, Msg.Msg, Msg.wParam, Msg.lParam) ;
   end;
end; (*AppWndProc*)

constructor TTaskBarMenu.Create(AOwner: TComponent) ;
begin
   if Assigned(thisOnce) then
   begin
     raise Exception.Create('Only one instance of this component can be used per application!') ;
   end
   else
   begin
     inherited;
     thisOnce := self;
     hookHandle := Application.Handle;
     Hook;
   end;
end; (*Create*)

destructor TTaskBarMenu.Destroy;
begin
   thisOnce := nil;
   UnHook;
   inherited;
end; (*Destroy*)

procedure TTaskBarMenu.Hook;
begin
   oldWndProc := Pointer(GetWindowLong(hookHandle, GWL_WNDPROC)) ;

   newWndProc := Classes.MakeObjectInstance(AppWndProc) ;

   if not (csDesigning in ComponentState) then SetWindowLong(hookHandle, GWL_WNDPROC, longint(newWndProc)) ;
end; (*Hook*)

procedure TTaskBarMenu.UnHook;
begin
   SetWindowLong(hookHandle, GWL_WNDPROC, longint(oldWndProc)) ;

   if Assigned(newWndProc) then Classes.FreeObjectInstance(newWndProc) ;

   NewWndProc := nil;
end; (*UnHook*)

end.


그럼..

+ -

관련 글 리스트
758 [Win32] 시스템 메뉴 내맘대로 2 - 작업표시줄 메뉴 바꾸기 장성호 8967 2008/03/18
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.