函数参考


_WinAPI_SetWindowRgn

设置窗口的窗口区域

#Include <WinAPI.au3>
_WinAPI_SetWindowRgn($hWnd, $hRgn [, $bRedraw])

参数

$hWnd 窗口句柄.
$hRgn 用于函数设置为窗口区域的区域句柄.
$bRedraw [可选参数] 指定区域设置后,系统是否刷新窗口.

返回值

成功: Nonzero
失败: 返回 0

注意/说明

 系统允许在窗口区域内的窗口绘图.
 系统不显示任何窗口的窗口区域以外的部分.
 函数被调用时, 系统将发送 WM_WINDOWPOSCHANGING 与 WM_WINDOWPOSCHANGED 消息到窗口.
 窗口的窗口区域坐标相对于窗口的左上角,而不是窗口的客户区.
 函数调用成功, 系统拥有 $hRgn 指定的区域句柄.
 系统不会创建区域的副本. 因此, 不要对此区域句柄调用其他函数.
 特别是不要删除这个区域句柄. 当不再需要时, 该系统将删除该区域的句柄.

相关

_WinAPI_CreateRectRgn, _WinAPI_CreateRoundRectRgn, _WinAPI_CombineRgn, _WinAPI_GetWindowRgn

详情参考

在MSDN中搜索


示例/演示


#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

; 获取窗口标题高度及窗口框架宽度 - 开启/关闭XP主题时可能不同
Global $htit = _WinAPI_GetSystemMetrics($SM_CYCAPTION)
Global $frame = _WinAPI_GetSystemMetrics($SM_CXDLGFRAME)

Local $gui = GUICreate("Test Windows regions", 350, 210)
Local $btn_default = GUICtrlCreateButton("Default region", 100, 30, 150)
Local $btn_round = GUICtrlCreateButton("Round region", 100, 60, 150)
Local $btn_buble = GUICtrlCreateButton("Buble region ", 100, 90, 150)
Local $btn_transparent = GUICtrlCreateButton("Transparent region", 100, 120, 150)
Local $btn_exit = GUICtrlCreateButton("Exit", 100, 150, 150)
GUISetState(@SW_SHOW)

Local $pos = WinGetPos($gui) ; 获取整个窗口大小(GUICreate定义的窗口不包含客户区)
Global $width = $pos[2]
Global $height = $pos[3]

Local $msg, $rgn
While 1
    $msg = GUIGetMsg()
    Select
        Case $msg = $GUI_EVENT_CLOSE Or $msg = $btn_exit
            ExitLoop

        Case $msg = $btn_default
            $rgn = _WinAPI_CreateRectRgn(0, 0, $width, $height)
            _WinAPI_SetWindowRgn($gui, $rgn)

        Case $msg = $btn_round
            $rgn = _WinAPI_CreateRoundRectRgn(0, 0, $width, $height, $width / 3, $height / 3)
            _WinAPI_SetWindowRgn($gui, $rgn)

        Case $msg = $btn_buble
            Local $rgn1 = _WinAPI_CreateRoundRectRgn(0, 0, $width / 2, $height / 2, $width / 2, $height / 2) ; 左上
            Local $rgn2 = _WinAPI_CreateRoundRectRgn($width / 2, 0, $width, $height / 2, $width / 2, $height / 2) ; 右上
            _WinAPI_CombineRgn($rgn1, $rgn1, $rgn2, $RGN_OR)
            _WinAPI_DeleteObject($rgn2)
            $rgn2 = _WinAPI_CreateRoundRectRgn(0, $height / 2, $width / 2, $height, $width / 2, $height / 2) ; 左下
            _WinAPI_CombineRgn($rgn1, $rgn1, $rgn2, $RGN_OR)
            _WinAPI_DeleteObject($rgn2)
            $rgn2 = _WinAPI_CreateRoundRectRgn($width / 2, $height / 2, $width, $height, $width / 2, $height / 2) ; 右下
            _WinAPI_CombineRgn($rgn1, $rgn1, $rgn2, $RGN_OR)
            _WinAPI_DeleteObject($rgn2)
            $rgn2 = _WinAPI_CreateRoundRectRgn(10, 10, $width - 10, $height - 10, $width, $height) ; 中间
            _WinAPI_CombineRgn($rgn1, $rgn1, $rgn2, $RGN_OR)
            _WinAPI_DeleteObject($rgn2)
            _WinAPI_SetWindowRgn($gui, $rgn1)

        Case $msg = $btn_transparent
            _GuiHole($gui, 40, 40, 260, 170)

    EndSelect
WEnd

; 将内部区域透明并添加控件
Func _GuiHole($h_win, $i_x, $i_y, $i_sizew, $i_sizeh)
    Local $outer_rgn, $inner_rgn, $combined_rgn

    $outer_rgn = _WinAPI_CreateRectRgn(0, 0, $width, $height)
    $inner_rgn = _WinAPI_CreateRectRgn($i_x, $i_y, $i_x + $i_sizew, $i_y + $i_sizeh)
    $combined_rgn = _WinAPI_CreateRectRgn(0, 0, 0, 0)
    _WinAPI_CombineRgn($combined_rgn, $outer_rgn, $inner_rgn, $RGN_DIFF)
    _WinAPI_DeleteObject($outer_rgn)
    _WinAPI_DeleteObject($inner_rgn)
    _AddCtrlRegion($combined_rgn, $btn_default)
    _AddCtrlRegion($combined_rgn, $btn_round)
    _AddCtrlRegion($combined_rgn, $btn_buble)
    _AddCtrlRegion($combined_rgn, $btn_transparent)
    _AddCtrlRegion($combined_rgn, $btn_exit)
    _WinAPI_SetWindowRgn($h_win, $combined_rgn)
EndFunc   ;==>_GuiHole

; 添加控件的范围到特定的区域
; 也考虑窗口标题/框架的大小
Func _AddCtrlRegion($full_rgn, $ctrl_id)
    Local $ctrl_pos, $ctrl_rgn

    $ctrl_pos = ControlGetPos($gui, "", $ctrl_id)
    $ctrl_rgn = _WinAPI_CreateRectRgn($ctrl_pos[0] + $frame, $ctrl_pos[1] + $htit + $frame, _
            $ctrl_pos[0] + $ctrl_pos[2] + $frame, $ctrl_pos[1] + $ctrl_pos[3] + $htit + $frame)
    _WinAPI_CombineRgn($full_rgn, $full_rgn, $ctrl_rgn, $RGN_OR)
    _WinAPI_DeleteObject($ctrl_rgn)
EndFunc   ;==>_AddCtrlRegion