wangms 发表于 2015-4-2 11:24:31

【已解决】GDI+绘制分层窗口不分层

本帖最后由 wangms 于 2015-4-7 08:58 编辑

GDI+绘制文本,设置$WS_EX_LAYERED,窗口为何不分层、窗口底色仍然存在?请大神指点,问题出在哪儿?
问题在这儿:1、经netegg指点,对$WS_EX_LAYERED创建分层窗口理解有误、应该是透明、而不是分层重叠的意思;
                  2、20#将控件背景色GUICtrlSetBkColor(-1, 0x888888)改为窗口背景色GUISetBkColor(0x888888, $hGui);
                  3、 52#画布颜色将FF不透明改为00透明。

代码如下:#include <APIConstants.au3>
#include <WinAPIEx.au3>
#include <GDIPlus.au3>
#include <GDIPlusEx.au3>

Opt("GUIOnEventMode", 1)

Local $sText = "Music site Spotify *compiled a list of the most-streamed female artists on International Women’s Day, and Rihanna *reigns supreme as the top female artist among all Spotify listeners worldwide, reported Reuters. This most-streamed female artist for the third year in a row had a smash hit with her Eminem collaboration, The Monster, last year. The song has been streamed over 200 million times on Spotify. With this service, users don’t download content, rather it is seamlessly delivered to them via the Internet. Katy Perry, Beyonce, Lana Del Rey and Lady Gaga were next up on the list." & @CRLF
$sText &= "新浪财经讯周一早盘,沪指高开低走后,盘中在地产的带领下,金融、有色、煤炭等权重集体发力,沪指拉升,再上3400点,突破前期3406点的高点,创出67个月来的新高;临近午间收盘,券商、银行、保险直线拉升,带动大盘走高;午后,沪指再新高后小幅回落,尾盘再度走高,创出2449.30点的67个月新高;截至收盘,沪指报3449.30点,涨2.26%;深成指报12017.77点,涨2.60%;创业板报2142.67点,涨3.56%。大数据100指数涨3.31%。两市共成交9118亿元。"

Global $hCallback = DllCallbackRegister("YourFunc", "int", "hWnd;uint;wparam;lparam");函数名,返回值,参数
Global $ptrCallback = DllCallbackGetPtr($hCallback)

$hGUI = GUICreate("分层窗口", 600, 500, -1 , -1, $WS_POPUP, BitOR($WS_EX_LAYERED, $WS_EX_TOPMOST, $WS_EX_TOOLWINDOW))
GUISetOnEvent($GUI_EVENT_SECONDARYUP, '_GUIDelete', $hGUI)
;$nCtrlId = GUICtrlCreatePic("", 0, 0, 600, 500,-1,$GUI_WS_EX_PARENTDRAG)
$nCtrlId = GUICtrlCreateLabel("", 0, 0, 600, 500, -1, $GUI_WS_EX_PARENTDRAG)
$hPicWnd = GUICtrlGetHandle($nCtrlId)

GUICtrlSetBkColor(-1, 0x888888)
_API_SetLayeredWindowAttributes($hGui, 0x888888)


;设置lable控件的处理函数,也就是所谓的控件子类化
Global $hOldProc = _WinAPI_SetWindowLong($hPicWnd, $GWL_WNDPROC, $ptrCallback)

GUISetState()

Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete()
Exit

Func YourFunc($hWnd, $iMsg, $wParam, $lParam)
      Local $au3Dir = RegRead("HKEY_LOCAL_MACHINE\SOFTWARE\AutoIt v3\Autoit", "InstallDir");au3安装目录
      Switch $iMsg
                Case $WM_PAINT
                        Local $tPAINTSTRUCT
                        Local $hDC = _WinAPI_BeginPaint($hWnd, $tPAINTSTRUCT)
                        ;获取控件长高
                        Local $HWND_CX = _WinAPI_GetWindowWidth($hWnd)
                        Local $HWND_CY = _WinAPI_GetWindowHeight($hWnd)
                        ;开始GDI+
                        _GDIPlus_Startup()
                        ;获取画布,这是从DC获取,还可以用_GDIPlus_GraphicsCreateFromHWND($hWnd)从控件句柄获取,使用完成要释放画布_GDIPlus_GraphicsDispose($hGraphics)
                        $hGraphics = _GDIPlus_GraphicsCreateFromHDC($hDC)
                        ;根据画布创建位图对象,我们等会的画图均是针对位图来操作的,也就是没有直接画在画布上,就是所谓的双缓冲画图
                        $hBitmap = _GDIPlus_BitmapCreateFromGraphics($HWND_CX, $HWND_CY, $hGraphics)
                        ;获取位图对象的画布,图就画在位图的画布上
                        $hBackbuffer = _GDIPlus_ImageGetGraphicsContext($hBitmap)
                        ;用颜色0xFFE0E0E0清除画布,GDI+的颜色全是ARGB格式,A是透明度,RGB是红绿蓝,这里FF就是不透明,E0E0E0是红绿蓝成分
                        _GDIPlus_GraphicsClear($hBackbuffer, 0xFFE0E0E0)
                        _GDIPlus_GraphicsSetSmoothingMode($hBackbuffer, 2);平滑模式,2为8*8抗距齿

                        ;纯色画刷_GDIPlus_BrushGetType($hBrush)返回值是0
;                        $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF0000)
;                        ;还可以用_GDIPlus_BrushSetFillColor($hBrush, $iARGB)设置颜色
;                        _GDIPlus_BrushDispose($hBrush);画刷用完要释放
;                        _GDIPlus_GraphicsDrawString($hBackbuffer, "纯色", 10, 60)


                                                $hBrush = _GDIPlus_BrushCreateSolid(0xFF00007F)         ;创建实心画笔对象.
                                                $hFormat = _GDIPlus_StringFormatCreate()                  ;创建字符串格式对象.
                                                $hFamily = _GDIPlus_FontFamilyCreate('Arial')            ;创建字体族对象.
                                                $hFont = _GDIPlus_FontCreate($hFamily, 16, 0)         ;创建字体对象.
                                                $tLayout = _GDIPlus_RectFCreate(0, 0, 600, 500)    ;创建 $tagGDIPRECTF(图形填充矩形) 结构.暂按特别高的高度、规定的宽度测量。
                                                $aInfo = _GDIPlus_GraphicsMeasureString($hBackbuffer,$sText, $hFont, $tLayout, $hFormat);测量字符串尺寸.
                                                $iFontHeight = _GDIPlus_FontGetHeight ( $hFont, $hBackbuffer )      ;获取当前指定图形对象中某种字体的行距单位.测量行距特别准确!比 GetStringDimensions、_GetTabbedStringSize 测量得要精确多得多。
                                                _GDIPlus_GraphicsDrawStringEx($hBackbuffer,$sText, $hFont, $aInfo, $hFormat, $hBrush)   ;绘制字符串(使用数据结构).
                                                _GDIPlus_BrushDispose($hBrush);画刷用完要释放

                        ;画在位图画布上的图形,在$hBitap上,把$hBitmap画入DC的画布,也就在DC上显示了,双缓冲画图时间再长,画入DC画布就一次操作,图形不会闪烁
                        _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBitmap, 0, 0, 600, 500)
                        _GDIPlus_BitmapDispose($hBitmap)
                        _GDIPlus_GraphicsDispose($hBackbuffer)
                        _GDIPlus_GraphicsDispose($hGraphics)
                        _GDIPlus_Shutdown()
                        _WinAPI_EndPaint($hWnd, $tPAINTSTRUCT)
                        Return 0
      EndSwitch
      Return _WinAPI_CallWindowProc($hOldProc, $hWnd, $iMsg, $wParam, $lParam);没有处理的消息让原先的处理程序处理
EndFunc   ;==>YourFunc

Func _API_SetLayeredWindowAttributes($hwnd, $i_transcolor, $Transparency = 255, $isColorRef = False)
      Local Const $AC_SRC_ALPHA = 1
      Local Const $ULW_ALPHA = 2
      Local Const $LWA_ALPHA = 0x2
      Local Const $LWA_COLORKEY = 0x1
      If Not $isColorRef Then
                $i_transcolor = Hex(String($i_transcolor), 6)
                $i_transcolor = Execute('0x00' & StringMid($i_transcolor, 5, 2) & StringMid($i_transcolor, 3, 2) & StringMid($i_transcolor, 1, 2))
      EndIf
      Local $Ret = DllCall("user32.dll", "int", "SetLayeredWindowAttributes", "hwnd", $hwnd, "long", $i_transcolor, "byte", $Transparency, "long", $LWA_COLORKEY + $LWA_ALPHA)
      Select
                Case @error
                        Return SetError(@error, 0, 0)
                Case $Ret = 0
                        Return SetError(4, 0, 0)
                Case Else
                        Return 1
      EndSelect
EndFunc   ;==>_API_SetLayeredWindowAttributes

Func _GUIDelete()
        GUIDelete()
        Exit
EndFunc   ;==>_GUIDelete

wangms 发表于 2015-4-2 11:25:21

自己顶下先。。。。。。。。。。。

wangms 发表于 2015-4-2 17:00:59

自己再顶一下。。。。。。。。。。。。。

yhxhappy 发表于 2015-4-2 21:21:49

本帖最后由 yhxhappy 于 2015-4-2 21:46 编辑

你的意思是想搞成窗口只显示内容,背景是透明的?下面是论坛上找的


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

Local $sText = "Music site Spotify *compiled a list of the most-streamed female artists on International Women’s Day, and Rihanna *reigns supreme as the top female artist among all Spotify listeners worldwide, reported Reuters. This most-streamed female artist for the third year in a row had a smash hit with her Eminem collaboration, The Monster, last year. The song has been streamed over 200 million times on Spotify. With this service, users don’t download content, rather it is seamlessly delivered to them via the Internet. Katy Perry, Beyonce, Lana Del Rey and Lady Gaga were next up on the list." & @CRLF
$sText &= "新浪财经讯周一早盘,沪指高开低走后,盘中在地产的带领下,金融、有色、煤炭等权重集体发力,沪指拉升,再上3400点,突破前期3406点的高点,创出67个月来的新高;临近午间收盘,券商、银行、保险直线拉升,带动大盘走高;午后,沪指再新高后小幅回落,尾盘再度走高,创出2449.30点的67个月新高;截至收盘,沪指报3449.30点,涨2.26%;深成指报12017.77点,涨2.60%;创业板报2142.67点,涨3.56%。大数据100指数涨3.31%。两市共成交9118亿元。"


$Form1 = GUICreate("窗体透明效果(控件不透明)", 600, 500, -1, -1, $WS_POPUP, $WS_EX_LAYERED)
$Label1 = GUICtrlCreateLabel($sText, 0, 0, 600, 450)
   GUICtrlSetFont(-1, 16, 400, 0, "Arial")
   GUICtrlSetColor(-1, 0x00007f)
$Button1 = GUICtrlCreateButton("EXIT", 128, 460, 89, 41)

GUISetBkColor(0xffffff)
_winapi_SetLayeredWindowAttributes ($Form1, 0xffffff, 0, $LWA_COLORKEY);这个函数实现的效果
GUISetState(@SW_SHOW)


While 1
      $nMsg = GUIGetMsg()
      Switch $nMsg
                Case $GUI_EVENT_CLOSE, $Button1
                        Exit

      EndSwitch
WEnd

wangms 发表于 2015-4-2 22:15:36

回复 4# yhxhappy
谢谢!我只想GDI+绘制的。

netegg 发表于 2015-4-2 22:24:51

GDI+绘制分层窗口不分层,这算中国话吗,居然没理解什么意思

wangms 发表于 2015-4-2 23:40:54

本帖最后由 wangms 于 2015-4-2 23:42 编辑

回复 6# netegg

老大,见你在坛子里,尽挑人家文字上的毛病,你那么热心、就应该帮人家解决问题,请问您老人家“分层窗口”的含义是什么?再说这是标题,能说那么多吗

netegg 发表于 2015-4-3 07:30:23

本帖最后由 netegg 于 2015-4-3 07:35 编辑

回复 7# wangms
首先,印象里没有所谓的分层窗口,即使有,按正常说是层叠窗口,是几个窗口同时显示,并设置相关的阴影,透明度一类的,本身就属于同一窗口,所以,什么叫分层窗口不分层,愿听详解
再说你这个问题,明白layered window是什么就太简单了,再做一个子窗口不就完了
另外,要是想用gdi,同样需要做两个dc,实现重叠遮盖,就好比在png图片上绘制控件一样
不用说我的事,我也不会随便就给代码

wangms 发表于 2015-4-3 08:24:31

回复 8# netegg


    谢谢!码不码倒无所谓,先不管你说的对与不对,这样回答人家的问题,首先会受到人家尊敬的!

wangms 发表于 2015-4-3 08:35:31

在这里我想多问各位大神一下,$WS_EX_LAYERED(分层窗口)这个参数概念,是指在一个GUI窗口中进行某某与某某的分层,例如底色与控件分层;还是指两个或两个以上GUI窗口重叠分层的意思。本人以前是后一种理解。

netegg 发表于 2015-4-3 08:54:06

本帖最后由 netegg 于 2015-4-3 09:02 编辑

$WS_EX_LAYERED是为了设置顶层窗口透明,不是为了分层
另外,回答不回答无所谓,你的问题本身确实存在问题,类似于,怎么让一个确定必然返回的返回值返回一个不是这个确定值的值
那个效果最后表现出来的确实可以做到类似于同一个窗口,但是并不改变分层与否

wangms 发表于 2015-4-3 09:02:47

回复 11# netegg

谢谢指教!以前根据这个字面意思容易让人理解为两个或两个窗口重叠分层的意思

wangms 发表于 2015-4-3 09:10:17

回复 11# netegg


    $WS_EX_LAYERED是为了设置顶层窗口透明,这个中文翻译或是参数含义准确!

netegg 发表于 2015-4-3 09:18:59

本帖最后由 netegg 于 2015-4-3 09:25 编辑

正常讨论而已,另外只所以不能用于子窗体,就是因为它本身就是个子窗体,或者说原有的主窗体本身就拥有一个子窗体(但没有具体句柄),
最后加的独立子窗口到底继承谁,关系无法确定

wangms 发表于 2015-4-3 09:28:15

回复 14# netegg

这个我就有点不能理解,例如Local $hCGui = GUICreate('', 280, 100, 0, 10, $WS_POPUP, $WS_EX_LAYERED + $WS_EX_MDICHILD, $hGUI)这个式样,不就是$WS_EX_LAYERED用于$WS_EX_MDICHILD子窗口吗?
页: [1] 2 3 4
查看完整版本: 【已解决】GDI+绘制分层窗口不分层