找回密码
 加入
搜索
查看: 8733|回复: 9

[系统综合] 自定义窗口类,字体设置、消息传递问题[已解决]

  [复制链接]
发表于 2013-5-11 16:58:15 | 显示全部楼层 |阅读模式
本帖最后由 seniors 于 2013-5-12 08:58 编辑


问题有三个:
[1],我想在注册窗口类时,或者创建窗口时设置好字体,用WM_SETFONT不知道怎么设置,用_WINAPI_SETFONT也不行,现在是在WM_PAINT里设置的,总觉得不舒服
原来是自定义窗口,什么内容多要自己记录,所以_WINAPI_SETFONT不起作用,谢谢P大.
下面二个问题不算严重,算解决了。

[2],GUIGetMsg()中为什么得不到按钮消息,在WM_COMMAND中才有消息
[3],程序退出时怎么样才能不报错,我以前没习惯加GUIDELETE这句的。
代码如下
#include "DUIbutton.au3"
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
$hgui = GUICreate("test", 300, 200)
;这个字体现在是固定写的,我想能自由设置
$b1 = _DirUIButoon_Create($hgui, "中文不好看", 10, 10, 90, 30)
$b2 = _DirUIButoon_Create($hgui, "测试按钮", 150, 10, 90, 30)
$b3 = GUICtrlCreateButton("标准按钮五", 10, 50, 90, 30)
GUISetState()

While 1
        $Msg = GUIGetMsg()
        Switch $Msg
                Case -3
                        ExitLoop
                        ;在这里case ID为什么不能用
        EndSwitch
WEnd
;不删除窗口,用DllCallbackFree会出错
GUIDelete()
Exit

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
        $nCtrlID = BitAND(0xffff, $wParam)
        Switch $nCtrlID
                Case $b1
                        MsgBox(0, "", "1111111111")
                Case $b2
                        MsgBox(0, "", "2222222222")
                Case $b3
                        MsgBox(0, "", "3333333333")
        EndSwitch
EndFunc   ;==>WM_COMMAND

#include "DUIbutton.au3"
把下面代码存为DUIbutton.au3
#include-once
#include <Constants.au3>
#include <APIConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "UDFGlobalID.au3"
#include <WinAPI.au3>
#include <WinAPIEx.au3>
#include <Memory.au3>
#include <GDIPlusex.au3>
#include <ButtonConstants.au3>


; #VARIABLES# ===================================================================================================================
Global $_ghDirUIButoonLastWnd
Global $Debug_Btn = False
; ===============================================================================================================================

; #CONSTANTS# ===================================================================================================================
Global Const $tagDirUIButoon_IMAGELIST = "ptr ImageList;" & $tagRECT & ";uint Align"
Global Const $tagDirUIButoon_SPLITINFO = "uint mask;handle himlGlyph;uint uSplitStyle;" & $tagSIZE

Global Const $__DirUIButoonCONSTANT_ClassName = "DirUIButoon"
Global $__DirUIButoon_tClass
Global Const $__DirUIButoonCONSTANT_GWL_STYLE = 0xFFFFFFF0
Global Const $__DirUIButoonCONSTANT_LR_LOADFROMFILE = 0x0010
Global Const $__DirUIButoonCONSTANT_LR_CREATEDIBSECTION = 0x2000

Global Const $__DirUIButoonCONSTANT_WS_TABSTOP = 0x00010000
Global Const $__DirUIButoonCONSTANT_WM_SETFONT = 0x0030
Global Const $__DirUIButoonCONSTANT_DEFAULT_GUI_FONT = 17

Global Const $tag__DirUIButoon_OBJECT_STRUCT = "hwnd hWnd;hwnd hBitmap;dword dwItemCount;ptr lpUserData;ptr lParam"

Global Const $DirUIButton_SELECTED = 0x0001
Global Const $DirUIButton_GRAYED = 0x0002
Global Const $DirUIButton_DISABLED = 0x0004
Global Const $DirUIButton_FOCUS = 0x0010
Global Const $DirUIButton_HOVER = 0x0040

; 获取当前进程的模块句柄
$__DirUIButoon_hInstance = _WinAPI_GetModuleHandle(0)

; 创建类光标
$__DirUIButoon_hCursor = _WinAPI_LoadCursor(0, 32512) ; IDC_ARROW

; 创建 DLL 回调函数 (窗口过程)
$__DirUIButoon_hProc = DllCallbackRegister('__DirUIButoon_WndProc', 'lresult', 'hwnd;uint;wparam;lparam')

; 创建并填充 $tagWNDCLASSEX 结构
$__DirUIButoon_tWCEX = DllStructCreate($tagWNDCLASSEX)
DllStructSetData($__DirUIButoon_tWCEX, 'Size', DllStructGetSize($__DirUIButoon_tWCEX))
DllStructSetData($__DirUIButoon_tWCEX, 'Style', 0)
DllStructSetData($__DirUIButoon_tWCEX, 'hWndProc', DllCallbackGetPtr($__DirUIButoon_hProc))
DllStructSetData($__DirUIButoon_tWCEX, 'ClsExtra', 0)
DllStructSetData($__DirUIButoon_tWCEX, 'WndExtra', 4)
DllStructSetData($__DirUIButoon_tWCEX, 'hInstance', $__DirUIButoon_hInstance)
DllStructSetData($__DirUIButoon_tWCEX, 'hIcon', 0)
DllStructSetData($__DirUIButoon_tWCEX, 'hCursor', $__DirUIButoon_hCursor)
DllStructSetData($__DirUIButoon_tWCEX, 'hBackground', _WinAPI_CreateSolidBrush(_WinAPI_GetSysColor($COLOR_3DFACE)))
DllStructSetData($__DirUIButoon_tWCEX, 'MenuName', 0)
DllStructSetData($__DirUIButoon_tWCEX, 'ClassName', _WinAPI_CreateString($__DirUIButoonCONSTANT_ClassName, $__DirUIButoon_tClass))
DllStructSetData($__DirUIButoon_tWCEX, 'hIconSm', 0)
; 注册窗口类
_WinAPI_RegisterClassEx($__DirUIButoon_tWCEX)

Func _DirUIButoon_Create($hWnd, $sText, $iX, $iY, $iWidth, $iHeight, $iStyle = -1, $iExStyle = -1)
        If Not IsHWnd($hWnd) Then
                ; Invalid Window handle for _GUICtrlButton_Create 1st parameter
                Return SetError(1, 0, 0)
        EndIf
        If Not IsString($sText) Then
                ; 2nd parameter not a string for _GUICtrlButton_Create
                Return SetError(2, 0, 0)
        EndIf
        Local $iForcedStyle = BitOR($__DirUIButoonCONSTANT_WS_TABSTOP, $__UDFGUICONSTANT_WS_VISIBLE, $__UDFGUICONSTANT_WS_CHILD, $BS_NOTIFY)

        If $iStyle = -1 Then
                $iStyle = $iForcedStyle
        Else
                $iStyle = BitOR($iStyle, $iForcedStyle)
        EndIf
        If $iExStyle = -1 Then $iExStyle = 0
        Local $nCtrlID = __UDF_GetNextGlobalID($hWnd)
        If @error Then Return SetError(@error, @extended, 0)
        Local $hButton = _WinAPI_CreateWindowEx($iExStyle, $__DirUIButoonCONSTANT_ClassName, $sText, $iStyle, $iX, $iY, $iWidth, $iHeight, $hWnd, $nCtrlID)
        _WinAPI_SetFont($hButton, _WinAPI_GetStockObject($__DirUIButoonCONSTANT_DEFAULT_GUI_FONT), True)
        ;下面这行对字体的设置不起作用
;~         _SendMessage($hButton, $__DirUIButoonCONSTANT_WM_SETFONT, _WinAPI_GetStockObject($__DirUIButoonCONSTANT_DEFAULT_GUI_FONT), True)
        Return $nCtrlID
EndFunc   ;==>_DirUIButoon_Create

Func _DirUIButoon_Destroy(ByRef $hWnd)
;~         If $Debug_Btn Then __UDF_ValidateClassName($hWnd, $__BUTTONCONSTANT_ClassName)
        If Not _WinAPI_IsClassName($hWnd, $__DirUIButoonCONSTANT_ClassName) Then Return SetError(2, 2, False)
        Local $Destroyed = 0
        If IsHWnd($hWnd) Then
                If _WinAPI_InProcess($hWnd, $_ghDirUIButoonLastWnd) Then
                        Local $nCtrlID = _WinAPI_GetDlgCtrlID($hWnd)
                        Local $hParent = _WinAPI_GetParent($hWnd)
                        $Destroyed = _WinAPI_DestroyWindow($hWnd)
                        Local $iRet = __UDF_FreeGlobalID($hParent, $nCtrlID)
                        If Not $iRet Then
                                ; can check for errors here if needed, for debug
                        EndIf
                Else
                        ; Not Allowed to Destroy Other Applications Control(s)
                        Return SetError(1, 1, False)
                EndIf
        Else
                $Destroyed = GUICtrlDelete($hWnd)
        EndIf
        If $Destroyed Then $hWnd = 0
        Return $Destroyed <> 0
EndFunc   ;==>_DirUIButoon_Destroy

Func __DirUIButoon_WndProc($hWnd, $iMsg, $wParam, $lParam)
        Local $buttonStat = _WinAPI_GetWindowLong($hWnd, $GWL_USERDATA)
        Local $bFocused = BitAND($buttonStat, $DirUIButton_FOCUS)
        Local $bGrayed = BitAND($buttonStat, BitOR($DirUIButton_GRAYED, $DirUIButton_DISABLED))
        Local $bSelected = BitAND($buttonStat, $DirUIButton_SELECTED)
        Local $bHover = BitAND($buttonStat, $DirUIButton_HOVER)
        Switch $iMsg
                Case $WM_PAINT;处理绘制信息
                        Local $tPaint
                        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPaint)
                        Local $HWND_CX = _WinAPI_GetWindowWidth($hWnd)
                        Local $HWND_CY = _WinAPI_GetWindowHeight($hWnd)
                        ;中间渐变填充
                        Local $aVertex[2][3] = [[0, 0, 0xFFFFFF],[$HWND_CX, $HWND_CY, 0xFFB206]]
                        If $bGrayed Then
                                $aVertex[0][2] = 0xFFFFFF
                                $aVertex[1][2] = 0xC0C0C0
                                _WinAPI_GradientFill($hDC, $aVertex)
                        EndIf
                        If $bHover Then
                                $aVertex[0][2] = 0xFFB206
                                $aVertex[1][2] = 0xFFFFFF
                                _WinAPI_GradientFill($hDC, $aVertex)
                        Else
                                _WinAPI_GradientFill($hDC, $aVertex)
                        EndIf
                        ;绘制边框
                        Local $tRect = _WinAPI_CreateRect(0, 0, $HWND_CX, $HWND_CY)
                        Local $hBrush = _WinAPI_GetStockObject($NULL_BRUSH)
                        Local $hPen = _WinAPI_CreatePen(0, 3, 0xC0C0C0)
                        Local $oldhPen = _WinAPI_SelectObject($hDC, $hPen)
                        _WinAPI_SelectObject($hDC, $hBrush)
                        _WinAPI_Rectangle($hDC, $tRect)
                        ;写按钮文字
                        _WinAPI_SelectObject($hDC, $oldhPen)
                        _WinAPI_DeleteObject($hPen)
                        _WinAPI_DeleteObject($hBrush)
                        Local $hFont = _WinAPI_GetStockObject($__DirUIButoonCONSTANT_DEFAULT_GUI_FONT);这里是固定用这个字体写了,我想能自由设置字体
                        _WinAPI_SelectObject($hDC, $hFont)
                        _WinAPI_SetBkMode($hDC, $TRANSPARENT)
                        If $bSelected Then _WinAPI_OffsetRect($tRect, 2, 2)
                        _WinAPI_DrawText($hDC, _WinAPI_GetWindowText($hWnd), $tRect, BitOR($DT_CENTER, $DT_SINGLELINE, $DT_VCENTER))
                        _WinAPI_DeleteObject($hFont)
                        ;如果焦点,绘制焦点框
                        If $bFocused Then __DirUIButoon__DrawFocusRect($hDC, 1, 1, $HWND_CX - 1, $HWND_CY - 1)
                        Return _WinAPI_EndPaint($hWnd, $tPaint)
                Case $WM_SETFOCUS;设置焦点
                        _WinAPI_SetWindowLong($hWnd, $GWL_USERDATA, $DirUIButton_FOCUS)
                        _WinAPI_InvalidateRect($hWnd, 0, False)
                Case $WM_KILLFOCUS;去除焦点
                        _WinAPI_SetWindowLong($hWnd, $GWL_USERDATA, 0x0)
                        _WinAPI_InvalidateRect($hWnd, 0, False)
                Case $WM_MOUSEMOVE;鼠标覆盖
                        If Not $bHover Then
                                _WinAPI_SetWindowLong($hWnd, $GWL_USERDATA, BitOR($buttonStat, $DirUIButton_HOVER))
                                _WinAPI_InvalidateRect($hWnd, 0, False)
                        EndIf
                        _WinAPI_TrackMouseEvent($hWnd, 0x00000002)
                Case $WM_MOUSELEAVE;鼠标离开
                        If $bSelected Then
                                _WinAPI_SetWindowLong($hWnd, $GWL_USERDATA, BitXOR($buttonStat, $DirUIButton_HOVER, $DirUIButton_SELECTED))
                        Else
                                _WinAPI_SetWindowLong($hWnd, $GWL_USERDATA, BitXOR($buttonStat, $DirUIButton_HOVER))
                        EndIf
                        _WinAPI_InvalidateRect($hWnd)
                Case $WM_LBUTTONDOWN;左键点击
                        _WinAPI_SetFocus($hWnd)
                        _WinAPI_SetWindowLong($hWnd, $GWL_USERDATA, BitOR($buttonStat, $DirUIButton_SELECTED, $DirUIButton_FOCUS))
                        _WinAPI_InvalidateRect($hWnd)
                Case $WM_LBUTTONUP;左键释放
                        If $bSelected Then
                                _WinAPI_SetWindowLong($hWnd, $GWL_USERDATA, BitXOR($buttonStat, $DirUIButton_SELECTED))
                                _WinAPI_InvalidateRect($hWnd)
                        EndIf
                        _WinAPI_PostMessage(_WinAPI_GetParent($hWnd), $WM_COMMAND, BitOR(_WinAPI_GetDlgCtrlID($hWnd), BitShift($BN_CLICKED, -16)), $hWnd)
;~                 Case $WM_SETFONT
;~                         $hFont = $wParam
;~                         $fRedraw = $lParam;_WinAPI_LoWord($lParam)
;~                         If $fRedraw Then _WinAPI_RedrawWindow($hWnd)
;~                 Case $WM_GETFONT
;~                         Return _WinAPI_GetStockObject($__DirUIButoonCONSTANT_DEFAULT_GUI_FONT)
        EndSwitch
        Return __DirUIButoon__DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
EndFunc   ;==>__DirUIButoon_WndProc


Func __DirUIButoon__DefWindowProc($hWnd, $iMsg, $wParam, $lParam)
        Local $iResult = DllCall("User32.dll", "lresult", "DefWindowProcW", "hwnd", $hWnd, "long", $iMsg, "wparam", $wParam, "lparam", $lParam)
        Return $iResult[0]
EndFunc   ;==>__DirUIButoon__DefWindowProc

Func __DirUIButoon_OnAutoItExit()
        _WinAPI_UnregisterClass($__DirUIButoon_tWCEX, $__DirUIButoon_hInstance)
;~     DllCallbackFree($__DirUIButoon_hProc)
EndFunc   ;==>__DirUIButoon_OnAutoItExit

Func __DirUIButoon__DrawFocusRect($hDC, $nLeft, $nTop, $nRight, $nBottom)
        Local $stRect = DllStructCreate("int;int;int;int")
        DllStructSetData($stRect, 1, $nLeft)
        DllStructSetData($stRect, 2, $nTop)
        DllStructSetData($stRect, 3, $nRight)
        DllStructSetData($stRect, 4, $nBottom)
        DllCall("user32.dll", "int", "DrawFocusRect", "hwnd", $hDC, "ptr", DllStructGetPtr($stRect))
        $stRect = 0
EndFunc   ;==>__DirUIButoon__DrawFocusRect

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2013-5-11 17:15:19 | 显示全部楼层
本帖最后由 seeking 于 2013-5-11 17:18 编辑

顶啊,问题搭不上
不过真是好东西,非常好看
发表于 2013-5-11 18:27:44 | 显示全部楼层
截取WM_SETFONT消息,wParam参数即是字体的句柄,自己保存这个句柄。
 楼主| 发表于 2013-5-11 20:27:42 | 显示全部楼层
回复 3# pusofalse
字体行了,又多个问题
Local $pObject = _MemGlobalAlloc(4 * 6)
        Local $tObject = DllStructCreate($tag__DirUIButoon_OBJECT_STRUCT, $pObject)
        Local $hFont = _WinAPI_GetStockObject($__DirUIButoonCONSTANT_DEFAULT_GUI_FONT)
        DllStructSetData($tObject, "hWnd", $hButton)
        DllStructSetData($tObject, "hBitmap", 0)
        DllStructSetData($tObject, "dwItemCount", 0)
        DllStructSetData($tObject, "buttonStata", 0)
        DllStructSetData($tObject, "deFont", $hFont);在这里设置了数据,为什么读不到
        DllStructSetData($tObject, "lParam", 0x12345678) ; 其他数据。
        _WinAPI_SetWindowLong($hButton, $GWL_USERDATA, $pObject)
为什么仅仅上面这些这些
__DirUIButoon__GetProp($hButton, "deFont")得不到数据
加这句__DirUIButoon__SetProp($hButton, "deFont", $hFont)
才能读到数据
发表于 2013-5-11 20:36:31 | 显示全部楼层
回复 4# seniors


    GetProp、SetProp是一对互补函数,分别用来读取、设置窗口的自定义属性,只有调用SetProp设置了属性以后,才能用GetProp读取。

GetWindowLong、SetWindowLong也是一组互补函数,用来读取、设置窗口的32位数据,只有调用SetWindowLong设置了数据了以后,才能用GetWindowLong读取,如果在SetWindowLong之前调用GetWindowLong,函数只会简单地返回0,GetProp、SetProp同理。

与GetProp配对的是SetProp,而非SetWindowLong。
 楼主| 发表于 2013-5-11 21:28:47 | 显示全部楼层
回复 5# pusofalse
谢谢,受教了,明白了。
发表于 2013-5-11 22:00:42 | 显示全部楼层
学习学习
发表于 2013-5-12 23:25:02 | 显示全部楼层
不错,从中学到很多。。。。谢谢楼上的p大
发表于 2013-7-7 20:03:43 | 显示全部楼层
从中学到很多
发表于 2013-8-23 20:40:23 | 显示全部楼层
看不懂先收藏
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-6-3 01:01 , Processed in 0.083095 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表