Q&A

  • CM_MOUSELEAVE, CM_MOUSEENTER 값을 못가져 옵니다
main form에서 sub form을 panel에 상속해 생성했습니다.

  frmNaMain := TfrmNaMain.Create(nil);
  frmNaMain.BorderStyle := bsNone;
  frmNaMain.Parent := plMain;
  frmNaMain.Align  := alClient;
  frmNaMain.Show;

잘되네요.

그런데 sub form에서 mouseover, mouseout을 체크하려 하는데
CM_MOUSELEAVE, CM_MOUSEENTER 값을 못가져 옵니다.

procedure TfrmNameMain.WndProc(var Message: TMessage);
begin
  if Message.LParam = Longint(Button1) then begin
     if (Message.Msg = CM_MOUSELEAVE) then begin
        Edit3.Text := '마우스가 떠날때';
     end;
     if (Message.Msg = CM_MOUSEENTER) then begin
        Edit3.Text := '마우스가 들어올때';
     end;
  end;
  inherited WndProc(Message);
end;

꼭 부탁드립니다.
4  COMMENTS
  • Profile
    이정욱 2008.10.13 02:18
    subform을 panel에 상속해 생성했다는게... 무슨 뜻인지요..?

    Panel에서 나가는것을 체크 하려면 위의 wndproc는 panel의 것을 가로 채서 사용해야 합니다.

    아니면 Panel을 상속받아서 새로운 컴포넌트에서 CM_MOUSELEAVE등을 처리 후 이용하셔야 하구요..
  • Profile
    배정은 2008.10.13 07:43
    질문설명이 많이 부족했습니다.
    제 생각만 한것 같습니다. 죄송 ^^

    frmNaMain.Parent := plMain; --> plMain : TPanel 입니다.

    Panel에 폼을 띄운거예요.
    Panel 안에 띄운 폼에서 CM_MOUSELEAVE, CM_MOUSEENTER 값을 못가져 옵니다.

  • Profile
    이정욱 2008.10.13 18:12
    아 네. 그렇군요. 그 폼 이 비어있다면 폼의 메세지를 가로채면 되겠지만, 그렇지 않은 경우에는 그냥 수동으로 처리해주셔야 할 것 같습니다..

    판넬 위에 폼이 올라가게 되면, 말씀 하신 메세지 들은 모두 그 폼에서 일어나게 됩니다.

    하지만 또 그 위에 여러가지 컨트롤들이 있다면 그 컨트롤에서 일어나게 되지요..

    즉, 원하시는 부분을 처리 하시려면, 타이머를 하나 놓으시고, GetCursorPos 같은 것으로 마우스의 위치를 가져와서 현재 마우스 위치에 따라 적절히 처리해 주셔야 할 것 같네요..

    아니면, frmNaMain 이라는 폼위에 올라가는 컴포넌트들을 죄다 커스터마이징 해서 마우스 메세지 들을 모두 폼으로 전달해주는 부분을 만들면, 그냥 폼 안에서 처리가 가능도 하긴 할거 같구요...

    가장 편한 방법은 위에서 말씀드린 타이머를 가지고 처리하시는것이 가장 편리한 방법이긴 할 것 같습니다..

    일단 판넬안에 폼을 넣는 방법이.. 정상적인 방법이 아닌 방법이므로.... 여러가지 꽁수들이 동원되어야 하겠네요...
  • Profile
    장성호 2008.10.13 20:31
    아래 코드는 님의 WndProc 코드입니다.

    <!--CodeS-->
    procedure TfrmNameMain.WndProc(var Message: TMessage);
    begin
    if Message.LParam = Longint(Button1) then begin //이부분을 빼야 할것 같은데요
    if (Message.Msg = CM_MOUSELEAVE) then begin
    Edit3.Text := '마우스가 떠날때';
    end;
    if (Message.Msg = CM_MOUSEENTER) then begin
    Edit3.Text := '마우스가 들어올때';
    end;
    end;
    inherited WndProc(Message);
    end;
    <!--CodeE-->

    그런데 코드에서 LParam이 Button1인지 아닌지 비교하는 부분이 왜 필요하죠?

    frmNameMain 폼의 MOUSEENTER / MOUSELEAVE 를 체크하려면
    if Message.LParam = Longint(Button1) then begin 이 비교 구분을 빼야 할것이구요


    만약
    frmNameMain 폼위에 있는 Button1의 MOUSEENTER / MOUSELEAVE 를 체크하려면
    Form의 WndProc에서는 할것이 아니라
    Button의 WndProc에서 해야 합니다.


    <!--CodeS-->
    var
    BtnOrgProc: TWndMethod;

    procedure TForm1.FormCreate(Sender: TObject);
    begin

    BtnOrgProc:=Button1.WindowProc;
    Button1.WindowProc:=ButtonWndProc;

    end;
    procedure TForm1.ButtonWndProc(var Msg: TMessage);
    begin

    if (Msg.Msg = CM_MOUSELEAVE) then
    begin
    Edit3.Text := '마우스가 떠날때';
    end;
    if (Msg.Msg = CM_MOUSEENTER) then
    begin
    Edit3.Text := '마우스가 들어올때';
    end;

    BtnOrgProc(Msg);

    end;


    <!--CodeE-->

    그럼..