zoukankan      html  css  js  c++  java
  • 使用buttonEdit写一个下拉的窗口

    • 在做一个下来窗口的时候,一般使用PopupEdit来实现,不过使用PopupEdit有一个缺点,那就是PopupEdit的下拉内容一出现那么编辑框就不能编辑了,为了解决这个问题,
      可以自己使用buttonEdit来模拟PopupEdit的操作,只有当点击下拉按钮的时候下拉框(也就是一个窗体)才会出现。
    • 大体思路,点击下拉按钮,出现一个新的窗体(ShowModal的形式),这个窗体的位置在buttonEdit的下面,点击其他的地方(非窗口中的内容)这个窗口会关闭。
    • 难点:1. 窗体的位置在ButtonEdit的下面。2. 当点击其他位置的时候这个窗口关闭。
    1. 窗口的位置:1. 获取ButtonEdit的位置坐标,将这个坐标转换为屏幕坐标。
    var
      EditorOrigin: TPoint;
      BtnEdt: TcxButtonEdit;
    begin
      EditorOrigin.Y := BtnEdt.Height;
      EditorOrigin.X := 0;
      EditorOrigin := BtnEdt.ClientToScreen(EditorOrigin);  
      ShowDialog(EditorOrigin.X, EditorOrigin.Y);
    end;
    
    1. 当点击其他位置的时候,这个窗口要关闭,那么肯定要重写Application.OnMessage; 当这个窗口不在active的时候 ModalResult := mrCancel;
    procedure CMMOUSEENTER(var Message: TMessage); message CM_MOUSEENTER;
    procedure CMMouseLeave(var Message: TMessage); message CM_MOUSELEAVE;
    procedure WMACTIVATE(var Msg: TWMActivate); message WM_ACTIVATE;
    procedure OnMessage(var Msg: TMsg; var Handled: Boolean);
    function ShowModal: Integer; override;
    
    function ShowDialog(X, Y: Integer): Boolean;
    begin
      Result := False;
      with TfrmDialog.Create(nil) do
      try
        Left := X;
        Top := Y;
        FOldOnMsg := Application.OnMessage;
        Application.OnMessage := OnMessage;
        ShowModal;
        Application.OnMessage := FOldOnMsg;
        if (ModalResult = mrOk) or (ModalResult = mrCancel) then
        begin
          Result := True;
          // do something
        end;
      finally
        Free;
      end;
    end;
    
    procedure TfrmDialog.CMMOUSEENTER(var Message: TMessage);
    begin
    // ReleaseCapture();
    end;
    
    procedure TfrmDialog.CMMouseLeave(var Message: TMessage);
    begin
    // SetCaptureControl(tlFlValue);
    end;
    
    procedure TfrmDialog.WMACTIVATE(var Msg: TWMActivate);
    begin
      if Msg.Active = WA_INACTIVE then
      begin
        ModalResult := mrCancel;
      end;
      inherited;
    end;
    
    function TfrmDialog.ShowModal: Integer;
    var
      // WindowList: TTaskWindowList;
      LSaveFocusState: TFocusState;
      // SaveCursor: TCursor;
      // SaveCount: Integer;
      // ActiveWindow: HWnd;
    begin
      LSaveFocusState := nil;
      CancelDrag;
      if GetCapture <> 0 then
        SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
      ReleaseCapture;
      Application.ModalStarted;
      try
        { RecreateWnd could change the active window }
        // ActiveWindow := GetActiveWindow;
        Include(FFormState, fsModal);
        if (PopupMode = pmNone) and (Application.ModalPopupMode <> pmNone) then
        begin
          RecreateWnd;
          HandleNeeded;
          { The active window might have become invalid, refresh it }
          // if (ActiveWindow = 0) or not IsWindow(ActiveWindow) then
          // ActiveWindow := GetActiveWindow;
        end;
        Screen.SaveFocusedList.Insert(0, Screen.FocusedForm);
        Screen.FocusedForm := Self;
        // SaveCursor := Screen.Cursor;
        Screen.Cursor := crDefault;
        // SaveCount := Screen.CursorCount;
        try
          Show;
          try
            SendMessage(Handle, CM_ACTIVATE, 0, 0);
            ModalResult := 0;
            repeat
              Application.HandleMessage;
              if Application.Terminated then
                ModalResult := mrCancel
              else
                if ModalResult <> 0 then
                CloseModal;
            until ModalResult <> 0;
            Result := ModalResult;
            SendMessage(Handle, CM_DEACTIVATE, 0, 0);
            // if GetActiveWindow <> Handle then ActiveWindow := 0;
          finally
            Hide;
          end;
        finally
          if Screen.SaveFocusedList.Count > 0 then
          begin
            Screen.FocusedForm := TCustomForm(Screen.SaveFocusedList.First);
            Screen.SaveFocusedList.Remove(Screen.FocusedForm);
          end
          else
            Screen.FocusedForm := nil;
          RestoreFocusState(LSaveFocusState);
          Exclude(FFormState, fsModal);
        end;
      finally
        Application.ModalFinished;
      end;
    end;
    
    procedure TfrmDialog.OnMessage(var Msg: TMsg;
      var Handled: Boolean);
    begin
      if Msg.message in [WM_NCLBUTTONDOWN, WM_NCRBUTTONDOWN] then
        Handled := True
      else
        if Assigned(FOldOnMsg) then
          FOldOnMsg(Msg, Handled);
    end;
    
  • 相关阅读:
    C语言经典算法100例-039-排序队列中插入新元素
    C语言经典算法100例-037-给10个数排序
    C语言经典算法100例-036-求100之内的素数
    C语言经典算法100例-032~35
    C语言经典算法100例-031-判断星期几
    安卓 短信页面设置(线性布局)
    CSS样式表
    HTML表单
    第1部分 HTML 表格
    多线程
  • 原文地址:https://www.cnblogs.com/chilanger/p/14200347.html
Copyright © 2011-2022 走看看