请问CommonDialog中颜色对话框的出现的位置如何更改?

programfish 2003-10-17 04:24:45
如上
...全文
74 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
hisofty 2003-10-17
  • 打赏
  • 举报
回复
看这个,理解其思路,稍作修改即可:

更动MsgBox Button 标题(CBT Hook)

来源:cww

如果我们使用MsgBox,并设定其Buttons为vbYesNo,则出来的Button有 "是(Y)" 与 "否(N)"
,有没有可能变成"Yes(Y)"和 "No(N)"呢,或者有没有办法设定MsgBox的位置呢?如果我们
可以在MsgBox显示出来之前取得其hWnd,便可以进而更动其位置或Button的标题了;其实这
真的有些困难,因为MsgBox一呼叫,该Process便进入等待MsgBox结束的状态,连Timer都
不会动,所以想取得MsgBox的进一步资讯似乎很难。所以只好借重CBT Hook。

CBT Hook是做什麽用的呢?它是before activating, creating, destroying,
minimizing, maximizing, moving, or sizing a window; before completing a
system command; before removing a mouse or keyboard event from the
system message queue; before setting the keyboard focus; or before
synchronizing with the system message queue.在以上的状况发生之前拦截到讯息。
所以了,这就达到我们的目的 -->可在MsgBox display前取得其hWnd了。取得hWnd後再
使用EmunChildWindows()取得MsgBox的Control视窗,并取得"Button"型态者,进而判
断其Caption,并进行更改之。

这个程式重点在说明CBT Hook,我想没有人会为了更动MsgBox内的Button而如此做,应
会自行写一个Form,而来呼叫它,并可设定其位置。

'以下在Form
Private Sub Command1_Click()
Call EnableHook
MsgBoxTitle = "MyTitle5"
MsgBox "haha", vbYesNo, MsgBoxTitle
Call FreeHook

End Sub

'以下程式在.Bas
Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lparam As Any) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function SetWindowText Lib "user32" Alias "SetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String) As Long
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lparam As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long

Public Const HCBT_ACTIVATE = 5
Public Const WH_CBT = 5

Public hHook As Long
Public MsgBoxTitle as String

Public Sub EnableHook()
If hHook = 0 Then
hHook = SetWindowsHookEx(WH_CBT, AddressOf HookProc, 0, App.ThreadID)
End If
End Sub
Public Sub FreeHook()
If hHook <> 0 Then
Call UnhookWindowsHookEx(hHook)
hHook = 0
End If
End Sub

Public Function HookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lparam As Long) As Long
If nCode < 0 Then
HookProc = CallNextHookEx(hHook, nCode, wParam, lparam)
Exit Function
End If
'当MsgBox Activate之前去更改Button的标题
If nCode = HCBT_ACTIVATE Then
Dim str5 As String
Dim len5 As Long, i As Long
str5 = String(255, 0)
len5 = 256
i = GetWindowText(wParam, str5, len5)
str5 = Left(str5, InStr(1, str5, Chr(0)) - 1)
'如果Active Window上的标题是MsgBox上的标题
'
If str5 = MsgBoxTitle Then
'取得MsgBox上的所有子window
Call EnumChildWindows(wParam, AddressOf ChgButtonTitle, 0)
End If
End If
HookProc = 0 '令待完成的动作继续完成,若为1,则取消原本要完成的动作
End Function

Private Function ChgButtonTitle(ByVal hwnd As Long, ByVal lparam As Long) As Long
Dim clsName As String, len5 As Long, i As Long
Dim Title As String
If hwnd = 0 Then
ChgButtonTitle = 0
Exit Function
End If
clsName = String(255, 0)
len5 = 256
i = GetClassName(hwnd, clsName, 256)
clsName = Left(clsName, InStr(1, clsName, Chr(0)) - 1)
Title = String(255, 0)
i = GetWindowText(hwnd, Title, 256)
Title = Left(Title, InStr(1, Title, Chr(0)) - 1)
'找到Button型态的子Window,并更改其上的标题
If clsName = "Button" Then
If Title = "是(&Y)" Then
Call SetWindowText(hwnd, "Yes(&Y)")
Else
If Title = "否(&N)" Then
Call SetWindowText(hwnd, "No(&N)")
End If
End If
End If
ChgButtonTitle = 1 '表示继续找下一个子Window
End Function
cjlong 2003-10-17
  • 打赏
  • 举报
回复
首先要找出CommonDialog是如何设置其对话框位置。首先在一个Form中放置一个CommonDialog控件,然后不断移动Form在屏幕的位置,并激活CommonDialog。你会发现CommonDialog总是出现在Form的左上角,当Form出现在屏幕的左侧或上部时,这一点非常明显。但当Form出现在屏幕下方或右侧时,CommonDialog会稍微做调整,以确保整个对话框都能显示在屏幕范围内。如果你的Form比较靠近屏幕中心,那么CommonDialog自然也会出现在屏幕中心。利用这一特点,我们可以建立一个空窗体,称为MyCDForm,然后在其上放置一个CommonDialog控件。这个MyCDForm只用来放置CommonDialog控件,没有其他用途。然后输入下面这个函数。
Private Function ChooseFile(argLeft As Single, argTop As Single) As Boolean
' 设置为没有文件被选择
ChooseFile = False
' 移动MyCDForm位置
MyCDForm.Left = argLeft
MyCDForm.Top = argTop
' 设置CommonDialog控件
MyCDForm!CommonDialog1.CancelError = True
On Error GoTo OpenError
' 显示CommonDialog
MyCDForm!CommonDialog1.ShowOpen
' 卸载MyCDForm
Unload MyCDForm
ChooseFile = True
Exit Function
OpenError:
' 用户按下Cancel键
Unload MyCDForm
Exit Function
End Function
当你的程序需要调用Open对话框时,使用ChooseFile就可以了。argLeft和argTop是Open对话框在屏幕上出现的位置的左上角的坐标。从这个函数可以看出,实际上我们是将MyCDForm的位置该为argLeft和argTop,而利用Open对话框的位置总是出现在其父窗口的左上角这一特性来改变Open对话框的屏幕位置。类似地,你也可以显示其他的对话框。如果你想让对话框出现在屏幕中央,则argLeft = (Screen.Width - 对话框宽度) \ 2,argTop = (Screen.Height - 对话框高度) \ 2。对于屏幕大小为800*600个像素,显示Open对话框的情况,这两个值大致均为1500
rainstormmaster 2003-10-17
  • 打赏
  • 举报
回复
http://www.china-askpro.com/msg1/qa38.shtml

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧