如何获取对话框中某个按钮的位置和大小(150分)

  • 主题发起人 主题发起人 c1
  • 开始时间 开始时间
C

c1

Unregistered / Unconfirmed
GUEST, unregistred user!
我从TOpenDialog派生了一个对话框类,请问如何才能获得原TOpenDialog对话框中OK和
Cancel两个按钮的位置和大小?
 
可以在你重载的 DoShow 中这样获得:
var
hDlgItm: HWND;
OKRect, CancelRect: TRect;
begin
hDlgItm := GetDlgItm(GetParent(Self.Handle), IDOK); //得到OK按钮的句柄
if hDlgItm <> 0 then
GetWindowRect(hDlgItm, OKRect);
hDlgItm := GetDlgItm(GetParent(Self.Handle), IDCANCEL); //得到CANCEL按钮的句柄
if hDlgItm <> 0 then
GetWindowRect(hDlgItm, CANCELRect);
...
end;
在 DoShow 中 Self.Handle 应该是有效的。好象在Dialog Execute 之前或之后,Handle
都是 0,Dialog 窗口不存在。
 
有一个问题GetWindowRect得到的是相对于屏幕的坐标,而在DoShow中通常用相对于对话框
的坐标来设置控件的位置,有什么方法可以在两种坐标中转换?
 
还有一个问题,当对话框的大小发生变化时,如何捕捉到这种变换,并做出相应的处理
呢?DoShow好像只在对话框第一次显示时被调用。
 
坐标转换利用 Windows 单元中声明的 ScreenToClient API 完成。
var
...
Point: TPoint;
begin
Point := CANCELRect.TopLeft; //绝对坐标,按钮的左上角
Windows.ScreenToClient(GetParent(Self.Handle), Point);//转换
//此时 Point 中的坐标已是相对于对话框的了
...
end;
至于对话框大小变化,应该可以为 WM_SIZE 消息写个消息处理程序,或重载 WndProc 过程
截获 WM_SIZE 消息,根据新的大小设置你自己的控件的位置。具体我没做,你可以试试。
 
为什么GetDlgItm(GetParent(Self.Handle), IDOK); 中需要用GetParent函数,在
DoShow中的Self.Handle不就是对画框的句柄吗?
 
因为 TOpen/SaveDialog 默认是 Explorer-Style 的对话框,创建时除了建立标准的如
OK 按钮等控件,还会根据资源中的子对话框模板创建一个用户自定义的子对话框,这个
子对话框作为对话框的一个子窗口,而 TOpen/SaveDialog 的 Handle 实际上是这个子对
话框的句柄,因此需要对 Self.Handle 调用 GetParent 以取得真正对话框的句柄。
你可以在 Windows SDK Help 中查找关于 "Explorer-Style custom Templates" 或
"Common Dialog" 的说明,我也还不是很明白。
 
接受答案了.
 

Similar threads

后退
顶部