|
HWND와 TButton은 다른놈입니다.
HWND를 TButton *으로 cast해서 access하려면 에러가 날겁니다.
HWND hWnd는 Button->Handle 입니다.
hwnd를 가지고 컨트롤로 변환시킬수는 없습니다.
hwnd를 가지고 컨트롤을 찾아야 하는것입니다.
방법1.
hWnd를 Form1의 Button1 , Button2 , Button3의 Handle과 각각 비교해서 Button을 찾는다.
-----------예제 1 ------------------
WNDPROC FOriginalProc[3];
LRESULT CALLBACK MyButtonProc2(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int tag=0;
if(hWnd==Form1->Button1->Handle)
{
if(uMsg==WM_MOUSEMOVE)Form1->Label1->Caption = Form1->Button1->Caption +" ( x , y ) = ( " + IntToStr(lParam&0x0000ffff)+ " , " + IntToStr(lParam>>16)+ " ) ";
tag=0;
}
else if(hWnd==Form1->Button2->Handle)
{
if(uMsg==WM_MOUSEMOVE)Form1->Label1->Caption = Form1->Button2->Caption +" ( x , y ) = ( " + IntToStr(lParam&0x0000ffff)+ " , " + IntToStr(lParam>>16)+ " ) ";
tag=1;
}
else if(hWnd==Form1->Button3->Handle)
{
if(uMsg==WM_MOUSEMOVE)Form1->Label1->Caption = Form1->Button3->Caption +" ( x , y ) = ( " + IntToStr(lParam&0x0000ffff)+ " , " + IntToStr(lParam>>16)+ " ) ";
tag=2;
}
return CallWindowProc((FARPROC)FOriginalProc[tag], hWnd, uMsg, wParam, lParam);
}
//----------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
FOriginalProc[0]=(WNDPROC)SetWindowLong(Button1->Handle,GWL_WNDPROC,(LONG)MyButtonProc2);
FOriginalProc[1]=(WNDPROC)SetWindowLong(Button2->Handle,GWL_WNDPROC,(LONG)MyButtonProc2);
FOriginalProc[2]=(WNDPROC)SetWindowLong(Button3->Handle,GWL_WNDPROC,(LONG)MyButtonProc2);
}
방법2
GWL_USERDATA 를 이용하여 Button *를 USERDATA에 설정해 둔다.
-----------예제 2 ------------------
WNDPROC FOriginalProc[3];
LRESULT CALLBACK MyButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
TButton *Btn=(TButton *)GetWindowLong(hWnd,GWL_USERDATA );
if(uMsg==WM_MOUSEMOVE)
{
if(Btn) Form1->Label1->Caption = Btn->Caption +" ( x , y ) = ( " + IntToStr(lParam&0x0000ffff)+ " , " + IntToStr(lParam>>16)+ " ) ";
}
if(Btn)
return CallWindowProc((FARPROC)FOriginalProc[Btn->Tag], hWnd, uMsg, wParam, lParam);
else
return 0;
}
//----------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Button1->Tag=0;
Button2->Tag=1;
Button3->Tag=2;
SetWindowLong(Button1->Handle,GWL_USERDATA,(LONG)Button1);
FOriginalProc[0]=(WNDPROC)SetWindowLong(Button1->Handle,GWL_WNDPROC,(LONG)MyButtonProc);
SetWindowLong(Button2->Handle,GWL_USERDATA,(LONG)Button2);
FOriginalProc[1]=(WNDPROC)SetWindowLong(Button2->Handle,GWL_WNDPROC,(LONG)MyButtonProc);
SetWindowLong(Button3->Handle,GWL_USERDATA,(LONG)Button3);
FOriginalProc[2]=(WNDPROC)SetWindowLong(Button3->Handle,GWL_WNDPROC,(LONG)MyButtonProc);
}
그럼...
이용태 님이 쓰신 글 :
: API를 이용하여 프로시져를 바꾸어 버튼의 캡션을 출력하는 테스트용 프로그램을 만들어보고 있습니다.
:
: 그런데.. CALLBACK 함수에서 넘어온 hWnd를 TButton으로 캐스팅하여... 버튼의 캡션을 얻을려고 하는데..
:
: 계속.. 계속.. 안됩니다...ㅡㅡ;;;;
:
: 어떻게 해야 버튼으로 캐스팅해서 쓸 수 있나요??
:
:
:
: //////////
: 방법1
: api수준에서 WINPROC를 이용하여 넘어오는 HWND로 어떤 버튼인지 구분하는 방법이 있구요
:
:
: DWORD *dwAdd;
: LRESULT CALLBACK MyButtonProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
: {
: switch(uMsg)
: {
: case WM_MOUSEMOVE:
:
: //방법1, 안됩니다..
: // btn->Handle = hWnd;
: // Form1->Label1->Caption = btn->Caption;
:
:
: //방법2, 안됩니다..
: // dwAdd = (DWORD*)hWnd;
: // Form1->Label1->Caption = ((TButton*)dwAdd)->Caption;
:
: default:
: return CallWindowProc((FARPROC)FOriginalProc, hWnd, uMsg, wParam, lParam);
: }
: }
:
:
:
:
:
: 장성호 님이 쓰신 글 :
: : sub-classing을 어떻게 하셨는지 의문이네요(여러가지 방법이 있어서..)
: :
: : 아래와 같이 하나의 메소드에 세개의 버튼을 모두 걸어두시면 구분이 힘들겠죠
: : Button1->WindowProc = ButtonProc;
: : Button2->WindowProc = ButtonProc;
: : Button3->WindowProc = ButtonProc;
: :
: :
: : 방법1
: : api수준에서 WINPROC를 이용하여 넘어오는 HWND로 어떤 버튼인지 구분하는 방법이 있구요
: :
: : 방법2
: : vcl를 TWndMethod 이용하여
: : 각 Button에 WindowProc를 따로 설정해서 하는 방법이 있을것 같습니다.
: : 아래와 같이..
: :
: : //---------------------------------------------------------------------------
: : typedef void __fastcall (__closure *TMyButtonSubProc)(TObject *Sender,TMessage &Msg);
: :
: : class TButtonSubClass : public TObject
: : {
: : TButton *Button;
: : TMyButtonSubProc BtnProc;
: : TWndMethod OrigProc;
: :
: : public:
: : __fastcall TButtonSubClass::TButtonSubClass(){};
: : void __fastcall TButtonSubClass::SetButton(TButton *btn,TMyButtonSubProc proc)
: : {
: : Button=btn;
: : BtnProc=proc;
: : if(Button)
: : {
: : OrigProc=Button->WindowProc;
: : Button->WindowProc=ButtonProc;
: : }
: : };
: : void __fastcall TButtonSubClass::ButtonProc(TMessage &Msg)
: : {
: : if(BtnProc)BtnProc(Button,Msg);
: : OrigProc(Msg);
: : };
: : __fastcall TButtonSubClass::~TButtonSubClass()
: : {
: : if(Button) Button->WindowProc=OrigProc;
: :
: : };
: : };
: :
: : //---------------------------------------------------------------------------
: : TButtonSubClass *BtnSub[3];
: :
: : void __fastcall TForm1::FormCreate(TObject *Sender)
: : {
: : BtnSub[0]=new TButtonSubClass;
: : BtnSub[0]->SetButton(Button1,ButtonSubProc);
: : BtnSub[1]=new TButtonSubClass;
: : BtnSub[1]->SetButton(Button2,ButtonSubProc);
: : BtnSub[2]=new TButtonSubClass;
: : BtnSub[2]->SetButton(Button3,ButtonSubProc);
: :
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TForm1::ButtonSubProc(TObject *Sender,TMessage &Msg)
: : {
: : if(Sender)
: : {
: : if(Msg.Msg==WM_MOUSEMOVE)
: : {
: : TButton *btn=(TButton *)Sender;
: : Label1->Caption= btn->Caption+" " + IntToStr(Msg.LParamLo)+ " "+ IntToStr(Msg.LParamHi);
: : }
: : }
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TForm1::FormDestroy(TObject *Sender)
: : {
: : delete BtnSub[0];
: : delete BtnSub[1];
: : delete BtnSub[2];
: : }
: : //---------------------------------------------------------------------------
: :
: : 그럼....
: :
: :
: :
: : 이용태 님이 쓰신 글 :
: : : 예를 들어 3개의 버튼(A, B, C)이 있습니다.
: : :
: : : 그리고 서브클래싱을 이용하여 마우스무브 메시지가 발생할 경우 특정 작업 a()를 버튼 A에 대해서만 수행합니다.
: : :
: : : 즉 버튼 A위에서 사용자가 마우스를 움직일 경우 a() 작업을 수행하고 B, C 버튼의 경우에는 a() 작업을 수행하지 않도록 할려고 합니다.
: : :
: : : 그런데 서브클래싱할땐 TMessage *msg만 넘어갈뿐, TObject *Sender 전달인자가 넘어가지 않기 때문에... 발생하는 마우스무브 메시지가 어떤 버튼에서 일어나는지 알수가 없더군요...
: : :
: : : 지금은 임시방편으로 마우스가 버튼 위로 올라갔을 경우, 불변수를 만들어놓아 현재 어떤 버튼위에 마우스가 올라갔는지를 알아내고, 그 불 변수를 이용하여 서브클래싱 함수에서 메시지를 걸러 a() 함수를 수행하고 있습니다.
: : :
: : : 이렇게 하는 방법말고.. 더 좋은 방법이 있지 않을까요??
: : :
: : : 현재 마우스무브 메시지가 어떤 버튼 컨트롤에서 일어나고 있는지를 알기위해선 어떻게 해야 할까요?
: : :
: : : 답변 부탁드립니다.
|