如果您对在Delphi中定位组件的提示感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于在Delphi中定位组件的提示的详细内容,我们还将为您解答delphi无法定位程序输入点
如果您对在Delphi中定位组件的提示感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于在Delphi中定位组件的提示的详细内容,我们还将为您解答delphi 无法定位程序输入点的相关问题,并且为您提供关于Delphi : WebBrowser、MSHTML在Delphi中的使用、Delphi TNotifyEvent是Delphi中基本通知事件的类型、delphi – 如何显示禁用控件的提示?、delphi-7 – 如何在delphi中获取appdata文件夹路径的有价值信息。
本文目录一览:- 在Delphi中定位组件的提示(delphi 无法定位程序输入点)
- Delphi : WebBrowser、MSHTML在Delphi中的使用
- Delphi TNotifyEvent是Delphi中基本通知事件的类型
- delphi – 如何显示禁用控件的提示?
- delphi-7 – 如何在delphi中获取appdata文件夹路径
在Delphi中定位组件的提示(delphi 无法定位程序输入点)
当点击右键(使用Style = WS_POPUP)时,我按照需要将月份日历显示为SHOWn,并在进行选择时隐藏它,用户导航,ESCapes等.
unit DateEditBare1; interface uses Winapi.Windows,Winapi.Messages,System.SysUtils,System.Variants,System.Classes,Vcl.Graphics,Vcl.Controls,Vcl.Forms,Vcl.Dialogs,Vcl.ExtCtrls,Vcl.ImgList,Vcl.ComCtrls,Vcl.StdCtrls,CommCtrl; type TespMonthCalendar = class(TMonthCalendar) procedure DoCloseUp(Sender: TObject); private fdroppedDown: boolean; FManagerHandle: HWND; // just a convenience to avoid having to assume its in the owner procedure CNNotify(var Message: TWMNotify); message CN_NOTIFY; procedure SetwindowDims; protected procedure CreateParams(var Params: TCreateParams); override; procedure CreateWnd; override; procedure KeyDown(var Key: Word; Shift: TShiftState); override; procedure WMActivate(var Msg: TWMActivate); message WM_ACTIVATE; procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW; end; TespDateEdit = class(TButtonedEdit) private FMonthCalendar: TespMonthCalendar; procedure DoRightButtonClick(Sender: TObject); protected procedure CreateWnd; override; procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW; public constructor Create(AOwner:TComponent); override; property MonthCalendar: TespMonthCalendar read FMonthCalendar write FMonthCalendar; end; TfrmDateEditBare1 = class(TForm) Edit1: TEdit; procedure FormCreate(Sender: TObject); private espDateEdit1: TespDateEdit; public end; var frmDateEditBare1: TfrmDateEditBare1; implementation {$R *.dfm} var _espdateEdit_ImageList: timageList=nil; //------------------------------------------------------------------------------ function MakeImageList(const ResNames: array of String): timageList; var ResBmp: TBitmap; I: Integer; begin { Create an image list. } _espdateEdit_ImageList := timageList.Create(nil); _espdateEdit_ImageList.Width := 24; _espdateEdit_ImageList.Height := 16; Result := _espdateEdit_ImageList; for I := 0 to Length(ResNames) - 1 do begin ResBmp := TBitmap.Create(); try { Try to load the bitmap from the resource. } try //ResBmp.LoadFromresourceName(HInstance,ResNames[I]); ResBmp.SetSize(24,16); ResBmp.Transparent := true; except ResBmp.Free(); Result.Free(); Exit; end; Result.Add(ResBmp,nil); finally ResBmp.Free; end; end; end; // Aowner is ignored for Now function GetimageList: timageList; begin if _espdateEdit_ImageList = nil then result := MakeImageList(['CalendarDrop','CalendarDropShifted']) else result := _espdateEdit_ImageList; end; //------------------------------------------------------------------------------ procedure TfrmDateEditBare1.FormCreate(Sender: TObject); begin espDateEdit1:= TespDateEdit.Create(self); espDateEdit1.Parent := self; espDateEdit1.left := 100; espDateEdit1.top := 100; espDateEdit1.Visible := true; end; //------------------------------------------------------------------------------ { TespMonthCalendar } procedure TespMonthCalendar.CMHintShow(var Message: TCMHintShow); begin inherited; if Message.HintInfo.HintControl=Self then begin Message.HintInfo.HintPos := self.ClientToScreen(Point(0,self.Height + 1)); Message.HintInfo.HideTimeout := 1000; // Message.HintInfo.ReshowTimeout := 1500; // setting this does not help end; end; procedure TespMonthCalendar.CreateParams(var Params: TCreateParams); begin inherited CreateParams(Params); with Params do begin Style := WS_POPUP; WindowClass.Style := WindowClass.Style or CS_SAVEBITS ; if CheckWin32Version(5,1) then WindowClass.Style := WindowClass.style or CS_DROPSHADOW; end; end; procedure TespMonthCalendar.CreateWnd; begin inherited; // Get/set the dimensions of the calendar SetwindowDims; end; procedure TespMonthCalendar.SetwindowDims; var ReqRect: TRect; MaxTodayWidth: Integer; begin FillChar(ReqRect,SizeOf(TRect),0); // get required rect Win32Check(MonthCal_GetMinReqRect(Handle,ReqRect)); // get max today string width MaxTodayWidth := MonthCal_GetMaxTodayWidth(Handle); // adjust rect width to fit today string if MaxTodayWidth > ReqRect.Right then ReqRect.Right := MaxTodayWidth; // set new height & width Width := ReqRect.Right ; Height:= ReqRect.Bottom ; end; (* SetwindowDims *) procedure TespMonthCalendar.CNNotify(var Message: TWMNotify); begin // hand off control of the selection to the boss i.e. the espDateEdit that I belong to // skip for demo ... just closeup if ( Message.NMHdr^.code = MCN_SELECT) then DoCloseUp(self); inherited; end; (*CNNotify*) procedure TespMonthCalendar.KeyDown(var Key: Word; Shift: TShiftState); begin if Key = VK_ESCAPE then begin Key := 0; DoCloseUp(self); end else inherited KeyDown(Key,Shift); end; procedure TespMonthCalendar.WMActivate(var Msg: TWMActivate); begin if (Msg.Active <> WA_INACTIVE) then // tell form to paint itself as though it still has focus (as we are no outside the form with POPUP) SendMessage(screen.ActiveForm.Handle,WM_NCACTIVATE,WParaM(True),-1) else DoCloseUp(self); inherited; end; procedure TespMonthCalendar.DoCloseUp(Sender: TObject); begin if fdroppedDown then begin fdroppedDown := false; Hide; // put focus back on dateedit so that checking is done if we leave here to go on to another control SendMessage(FManagerHandle,WM_ACTIVATE,-1); // less assumptions this way end; end; //------------------------------------------------------------------------------ { TespDateEdit } procedure TespDateEdit.CMHintShow(var Message: TCMHintShow); begin inherited; if Message.HintInfo.HintControl=Self then Message.HintInfo.HintPos := self.ClientToScreen(Point(0,21)); end; constructor TespDateEdit.Create(AOwner: TComponent); begin inherited Create(AOwner); if not(csDesigning in ComponentState) then begin FmonthCalendar := TespMonthCalendar.Create(self); self.hint := 'DUMMY HINT for Edit Box'; FMonthCalendar.Hint := 'Select required Date,' + ^M^J + 'or ESCape to close the calendar.'; FMonthCalendar.ShowHint := true; end; Width := 100; Height := 21; Images := GetimageList; Text := ''; // FormatdateTime('dd/mm/yy',Date); // not for demo ShowHint := True; DoubleBuffered := true; // reduces flicker when passing thru and within control RightButton.ImageIndex := 0; RightButton.pressedImageIndex := 1; RightButton.Visible := True; OnRightButtonClick := DoRightButtonClick; end; procedure TespDateEdit.CreateWnd; var P: TWinControl; begin inherited CreateWnd; if not(csDesigning in ComponentState) then begin FMonthCalendar.left := -900; P := self.Parent; while (P <> nil ) and not ( P is TCustomForm ) do P := P.parent; FmonthCalendar.Parent := P; // ie form (or the topmost non nil entry in the tree) FmonthCalendar.FManagerHandle := self.Handle; FMonthCalendar.Hide; FmonthCalendar.OnExit := FmonthCalendar.DoCloseUp; end; end; procedure TespDateEdit.DoRightButtonClick(Sender: TObject); var dt: Tdate; TopLeft: TPoint; Rect: TRect; begin if FmonthCalendar.fdroppedDown then begin FMonthCalendar.DoCloseUp(nil); exit; end; // load non-zero date into calendar as the selected date ... skip for demo TopLeft := self.ClientToScreen(Point(0,0)); // i.e. screen co-ords of top left of edit Box monthCalendar.left := TopLeft.X - 3 ; // shift a poopsie to line up visually monthCalendar.Top := TopLeft.Y + self.Height - 2; // only move it if it exceeds screen bounds ... skip this for demo FmonthCalendar.fdroppedDown := true; MonthCal_SetCurrentView(FmonthCalendar.handle,MCMV_MONTH); FmonthCalendar.Show; // showing is not enough - need to grab focus to get kbd events happening on the calendar FmonthCalendar.SetFocus; inherited OnRightButtonClick; end; //------------------------------------------------------------------------------ initialization finalization FreeAndNil(_espdateEdit_ImageList); end.
现在,我想为编辑框和TMonthCalendar添加单独的提示,但我想确保显示的提示不会模糊相关控件.
对于编辑框,我已经成功拦截了CM_HINTSHOW消息,并设置了HintInfo.HintPos来实现这一点.到现在为止还挺好.
问题1:更新:我现在已经显示了.最初我已经将提示的文本设置为包含Pipe字符,因此我可以使用TCustomHint.删除管道符,导致提示显示.但是这个提示不会隐藏自己,它会在TmonthCalendar显示时停留在屏幕上.我怎样才能让它“自我隐藏”?
问题2:如果我使用TCustomHint进行任一控制,则CMHintShow过程永远不会触发.所以,如果我确实想要使用TCustomHint进行额外控制,那么它如何改变定位策略呢?
(我不想在“应用程序”级别做任何事情,例如通过OnShowHint – 它必须特定于这些控件)
解决方法
原因是,VCL假定提示控件是子窗口,这是因为它的Parent属性不是nil.在问题中的代码的情况下,尽管月历通过将其变为弹出窗口而浮动,但是其父级仍然是VCL知道它的形式.这会导致Application的ActivateHint过程中的提示矩形的计算出错.另一方面,Application的HintMouseMessage过程并不关心控件是否是父级.然后会发生什么,虽然你没有在控件上移动鼠标指针,但是VCL推断鼠标指针连续离开提示边界然后重新进入.
以下是该问题的简化复制:
unit Unit1; interface uses Winapi.Windows,Vcl.StdCtrls; type TPanel = class(vcl.extctrls.TPanel) protected procedure CreateParams(var Params: TCreateParams); override; end; TForm1 = class(TForm) Button1: TButton; Panel1: TPanel; procedure FormCreate(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} { TPanel } procedure TPanel.CreateParams(var Params: TCreateParams); begin inherited; Params.Style := WS_POPUPWINDOW or WS_THICKFRAME; end; { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin Button1.Hint := 'Button1'; Panel1.Hint := 'Panel1'; ShowHint := True; Application.HintHidePause := 1000; Left := 0; Top := 0; Panel1.ParentBackground := False; Panel1.Left := 0; Panel1.Height := 50; Panel1.Top := Top + Height; end; end.
在上面的代码中,按钮的提示会在超时时隐藏,另一方面,面板的提示会在隐藏后重新显示.我故意将窗口定位到它们的位置,以便在激活提示时可以观察指针位置的重要性.如果从下面输入指向面板的鼠标指针,提示将只显示一次然后隐藏.但是,如果从上面进入面板,您将看到问题所在.
修复很简单,您可以修改CM_HINTSHOW消息处理程序中的提示矩形.由于控制是浮动的,因此不需要复杂的计算.相应的修改后的复制案例,它还修复了问题中的日历:
type TPanel = class(vcl.extctrls.TPanel) protected procedure CreateParams(var Params: TCreateParams); override; procedure CMHintShow(var Message: TCMHintShow); message CM_HINTSHOW; end; TForm1 = class(TForm) ... { TPanel } procedure TPanel.CMHintShow(var Message: TCMHintShow); begin inherited; if (GetAncestor(Handle,GA_ROOT) = Handle) and Assigned(Parent) then Message.HintInfo.CursorRect := Rect(0,Width,Height); end;
至于问题2,遗憾的是,自定义提示窗口似乎没有设计位置.提示窗口是在本地创建的,没有任何简洁的方法来获取它或以任何其他方式指定其位置.我能想到的唯一方法是覆盖一个自定义提示的绘制方法,它将提示窗口公开为参数.因此,我们可以在收到绘制消息后立即重新定位提示窗口.
这是一个工作示例(对于普通(非浮动)控件):
unit Unit1; interface uses Winapi.Windows,Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} type TMyCustomHint = class(TCustomHint) private FControl: TControl; public procedure NCPaintHint(Hintwindow: TCustomHintwindow; DC: HDC); override; end; procedure TMyCustomHint.NCPaintHint(Hintwindow: TCustomHintwindow; DC: HDC); var Pt: TPoint; begin Pt := FControl.ClientToScreen(Point(0,0)); SetwindowPos(Hintwindow.Handle,Pt.X,Pt.Y + FControl.Height,SWP_NOSIZE or SWP_NOZORDER or SWP_NOACTIVATE); inherited; end; //-------- procedure TForm1.FormCreate(Sender: TObject); begin ShowHint := True; Button1.Hint := 'button1 hint'; Button1.CustomHint := TMyCustomHint.Create(Self); TMyCustomHint(Button1.CustomHint).FControl := Button1; end; end.
Delphi : WebBrowser、MSHTML在Delphi中的使用
总结
以上是小编为你收集整理的Delphi : WebBrowser、MSHTML在Delphi中的使用全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
Delphi TNotifyEvent是Delphi中基本通知事件的类型
总结
以上是小编为你收集整理的Delphi TNotifyEvent是Delphi中基本通知事件的类型全部内容。
如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。
delphi – 如何显示禁用控件的提示?
我试图处理表单的OnMouseMove并执行类似的操作
procedure Tdlg.pnlTopMouseMove(Sender: TObject;Shift: TShiftState; X,Y: Integer); var point: TPoint; checkBoxCursorPos: TPoint; begin inherited; point.X := X; point.Y := Y; checkBoxCursorPos := chkBx.ScreenToClient(point); if (PtInRect(chkBx.ClientRect,checkBoxCursorPos)) then begin if(chkBx.Enabled) then chkBx.Hint := 'Enabled' else chkBx.Hint := 'disabled' ; Application.ShowHint := True; end; end;
但条件PtinRect不满意.我做错了什么?
解决方法
启用CheckBox时,将使用复选框的提示,而禁用CheckBox时将使用标签的提示.
更新:刚看到Bummi在评论中提到了类似的想法.
delphi-7 – 如何在delphi中获取appdata文件夹路径
begin Winexec(PAnsichar('%appdata%\TEST.exe'),sw_show); end; end.
但没有工作.
@R_301_5609@
uses ...,SysUtils; function GetPathToTestExe: string; begin Result := SysUtils.GetEnvironmentvariable('APPDATA'); if Result <> '' then Result := IncludeTrailingPathDelimiter(Result) + 'TEST.exe'; end;
uses ...,Windows; var Path: string; begin Path = GetPathToTestExe; if Path <> '' then WinExec(PAnsiChar(Path),SW_SHOW); end;
或者:
uses ...,SysUtils,Windows; function GetPathToTestExe: string; var Path: array[0..MAX_PATH+1] of Char; begin if ExpandEnvironmentStrings('%APPDATA%',Path,Length(Path)) > 1 then Result := IncludeTrailingPathDelimiter(Path) + 'TEST.exe' else Result := ''; end;
获取APPDATA文件夹路径的更可靠(和官方)方式是使用SHGetFolderPath()(或Vista上的SHGetKNownFolderPath()):
uses ...,Windows,SHFolder; function GetPathToTestExe: string; var Path: array[0..MAX_PATH] of Char; begin if SHGetFolderPath(0,CSIDL_APPDATA,SHGFP_TYPE_CURRENT,Path) = S_OK then Result := IncludeTrailingPathDelimiter(Path) + 'TEST.exe' else Result := ''; end;
但是,无论如何,自Windows 95以来,WinExec()已被弃用,你真的应该使用CreateProcess()代替:
uses ...,Windows; var Path: String; si: TStartupInfo; pi: TProcessinformation; Path := GetPathToTetExe; if Path <> '' then begin ZeroMemory(@si,SizeOf(si)); si.cb := SizeOf(si); si.dwFlags := STARTF_USESHOWWINDOW; si.wShowWindow := SW_SHOW; if CreateProcess(nil,PChar(Path),nil,FALSE,@si,pi) begin //... CloseHandle(pi.hThread); CloseHandle(pi.hProcess); end; end;
今天关于在Delphi中定位组件的提示和delphi 无法定位程序输入点的介绍到此结束,谢谢您的阅读,有关Delphi : WebBrowser、MSHTML在Delphi中的使用、Delphi TNotifyEvent是Delphi中基本通知事件的类型、delphi – 如何显示禁用控件的提示?、delphi-7 – 如何在delphi中获取appdata文件夹路径等更多相关知识的信息可以在本站进行查询。
本文标签: