半透明窗体问题已经解决,但是怎么解释这些代码?求教!(100分)

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

cowbird

Unregistered / Unconfirmed
GUEST, unregistred user!
以下代码是出于http://www.delphibbs.com/delphibbs/dispq.asp?lid=603975<br>我学习了下,是可以做到半透明窗体,且覆盖在桌面顶层,而不影响覆盖在下面的程序操作<br><br>但是是啥意思,请教各位,<br>我翻了API的书,SetWindowLong GetWindowLong是设置和获取窗口标记长字,不懂:(<br>还有SetLayeredWindowAttributes是仅仅对窗口做透明处理么?怎么不可以单独使用?<br><br>const<br>&nbsp; WS_EX_LAYERED = $80000;<br>&nbsp; WS_EX_TRANSPARENT = $20;<br>&nbsp; LWA_ALPHA = $2;<br><br>procedure TForm2.Button1Click(Sender: TObject);<br>begin<br>&nbsp; SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);<br>&nbsp; SetLayeredWindowAttributes(Handle, 0, 255, LWA_ALPHA);<br>&nbsp; SetWindowLong(Handle, GWL_EXSTYLE, OldStyle Or WS_EX_LAYERED Or WS_EX_TRANSPARENT);<br>end;<br><br>end.
 
不好意思,上面代码不完整<br>const<br>&nbsp; WS_EX_LAYERED = $80000;<br>&nbsp; WS_EX_TRANSPARENT = $20;<br>&nbsp; LWA_ALPHA = $2;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; OldStyle: Integer;<br>begin<br>&nbsp; OldStyle := GetWindowLong(Handle, GWL_EXSTYLE);<br>&nbsp; SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);<br>&nbsp; SetLayeredWindowAttributes(Handle, 0, 150, LWA_ALPHA);<br>&nbsp; SetWindowLong(Handle, GWL_EXSTYLE, OldStyle Or WS_EX_LAYERED Or WS_EX_TRANSPARENT);<br>end;<br>end.
 
SetLayeredWindowAttributes &nbsp;函数只对具有WS_EX_LAYERED属性的窗体才起作用<br>通常的窗体默认是不包含这个属性的<br>所以调用SetLayeredWindowAttributes &nbsp;之前要用SetWindowLong 使窗体具有<br>WS_EX_LAYERED属性
 
SetWindowLong Function<br><br>--------------------------------------------------------------------------------<br><br><br>The SetWindowLong function changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory.<br><br>Note &nbsp;This function has been superseded by the SetWindowLongPtr function. To write code that is compatible with both 32-bit and 64-bit versions of Microsoft&amp;reg; Windows&amp;reg;, use the SetWindowLongPtr function.<br><br>Syntax<br><br>LONG SetWindowLong( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;HWND hWnd,<br>&nbsp; &nbsp; int nIndex,<br>&nbsp; &nbsp; LONG dwNewLong<br>);<br>Parameters<br><br>hWnd<br>[in] <br>Handle to the window and, indirectly, the class to which the window belongs.<br><br>Windows 95/98/Me: The SetWindowLong function may fail if the window specified by the hWnd parameter does not belong to the same process as the calling thread.<br><br>nIndex<br>[in] Specifies the zero-based offset to the value to be set. Valid values are in the range zero through the number of bytes of extra window memory, minus the size of an integer. To set any other value, specify one of the following values. <br>GWL_EXSTYLE<br>Sets a new extended window style. For more information, see CreateWindowEx. <br>GWL_STYLE<br>Sets a new window style.<br>GWL_WNDPROC<br>Sets a new address for the window procedure.<br><br>Windows NT/2000/XP: You cannot change this attribute if the window does not belong to the same process as the calling thread.<br><br>GWL_HINSTANCE<br>Sets a new application instance handle.<br>GWL_ID<br>Sets a new identifier of the window.<br>GWL_USERDATA<br>Sets the user data associated with the window. This data is intended for use by the application that created the window. Its value is initially zero.<br>The following values are also available when the hWnd parameter identifies a dialog box.<br>DWL_DLGPROC<br>Sets the new address of the dialog box procedure.<br>DWL_MSGRESULT<br>Sets the return value of a message processed in the dialog box procedure.<br>DWL_USER<br>Sets new extra information that is private to the application, such as handles or pointers.<br>dwNewLong<br>[in] Specifies the replacement value. <br>Return Value<br><br>If the function succeeds, the return value is the previous value of the specified 32-bit integer.<br><br>If the function fails, the return value is zero. To get extended error information, call GetLastError. <br><br>If the previous value of the specified 32-bit integer is zero, and the function succeeds, the return value is zero, but the function does not clear the last error information. This makes it difficult to determine success or failure. To deal with this, you should clear the last error information by calling SetLastError(0) before calling SetWindowLong. Then, function failure will be indicated by a return value of zero and a GetLastError result that is nonzero.<br><br><br><br><br>Remarks<br><br>Certain window data is cached, so changes you make using SetWindowLong will not take effect until you call the SetWindowPos function. Specifically, if you change any of the frame styles, you must call SetWindowPos with the SWP_FRAMECHANGED flag for the cache to be updated properly. <br><br>If you use SetWindowLong with the GWL_WNDPROC index to replace the window procedure, the window procedure must conform to the guidelines specified in the description of the WindowProc callback function. <br><br>If you use SetWindowLong with the DWL_MSGRESULT index to set the return value for a message processed by a dialog procedure, you should return TRUE directly afterwards. Otherwise, if you call any function that results in your dialog procedure receiving a window message, the nested window message could overwrite the return value you set using DWL_MSGRESULT. <br><br>Calling SetWindowLong with the GWL_WNDPROC index creates a subclass of the window class used to create the window. An application can subclass a system class, but should not subclass a window class created by another process. The SetWindowLong function creates the window subclass by changing the window procedure associated with a particular window class, causing the system to call the new window procedure instead of the previous one. An application must pass any messages not processed by the new window procedure to the previous window procedure by calling CallWindowProc. This allows the application to create a chain of window procedures. <br><br>Reserve extra window memory by specifying a nonzero value in the cbWndExtra member of the WNDCLASSEX structure used with the RegisterClassEx function. <br><br>You must not call SetWindowLong with the GWL_HWNDPARENT index to change the parent of a child window. Instead, use the SetParent function. <br><br>If the window has a class style of CS_CLASSDC or CS_OWNDC, do not set the extended window styles WS_EX_COMPOSITED or WS_EX_LAYERED.<br><br>SetWindowLongW is supported by the Microsoft Layer for Unicode (MSLU). SetWindowLongA is also supported to provide more consistent behavior across all Windows operating systems. To use these versions, you must add certain files to your application, as outlined in Microsoft Layer for Unicode on Windows 95/98/Me Systems.<br>
 
感谢glacieret:<br>能不能详细的解释的一下,谢谢<br>const<br>&nbsp; WS_EX_LAYERED = $80000; //$80000是啥意思,我从来没用过,地址?一定要80000么?<br>&nbsp; WS_EX_TRANSPARENT = $20; //同上?<br>&nbsp; LWA_ALPHA = $2; //同上?<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; OldStyle: Integer;<br>begin<br>&nbsp; OldStyle := GetWindowLong(Handle, GWL_EXSTYLE); &nbsp;//啥意思?<br>&nbsp; SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_LAYERED);//啥意思?<br>&nbsp; SetLayeredWindowAttributes(Handle, 0, 150, LWA_ALPHA);<br>&nbsp; SetWindowLong(Handle, GWL_EXSTYLE, OldStyle Or WS_EX_LAYERED Or WS_EX_TRANSPARENT);//和上面有啥不同?<br>end;<br>end.<br>&nbsp;<br>上面我把问题都列出了,麻烦请在指导一下,愿意再奉上100分<br>SetLayeredWindowAttributes &nbsp;函数只对具有WS_EX_LAYERED属性的窗体才起作用<br>那么WS_EX_LAYERED是$80000规定的么?
 
onst<br>&nbsp; WS_EX_LAYERED = $80000; //$80000是啥意思,我从来没用过,地址?一定要80000么?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [red]这个是MS定义的常量 delphi 6/7 Windows 单元有 [/red] &nbsp;<br>&nbsp; WS_EX_TRANSPARENT = $20; //同上?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Yes<br>&nbsp; LWA_ALPHA = $2; //同上?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Yes<br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br>&nbsp; OldStyle: Integer;<br>begin<br>&nbsp; OldStyle := GetWindowLong(Handle, GWL_EXSTYLE); &nbsp;//啥意思?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; / Retrieves the extended window styles<br>&nbsp; SetWindowLong(Handle, GWL_EXSTYLE, OldStyle or WS_EX_LAYERED);//啥意思?<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /Sets a new extended window style &nbsp;<br>&nbsp; SetLayeredWindowAttributes(Handle, 0, 150, LWA_ALPHA);<br>&nbsp; SetWindowLong(Handle, GWL_EXSTYLE, OldStyle Or WS_EX_LAYERED Or WS_EX_TRANSPARENT);//和上面有啥不同?<br>&nbsp; &nbsp;/这句我认为多余 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>end;<br><br>end.<br>&nbsp;<br>上面我把问题都列出了,麻烦请在指导一下,愿意再奉上100分<br>SetLayeredWindowAttributes &nbsp;函数只对具有WS_EX_LAYERED属性的窗体才起作用<br>那么WS_EX_LAYERED是$80000规定的么? <br><br>[red]另[/red]<br>在delphi 6 / 7 中<br>可以用AlphaBlend 和 AlphaBlendValue 这两个属性完成这件事,不用自己写代码<br>至于具体参数含义,你还是去查MSDN 吧
 
glacieret应该回答的不错,但是还是有点错误,即使使用aplhaBlend(限win2000)<br>以下代码还是一定要的<br><br>OldStyle := GetWindowLong(Handle, GWL_EXSTYLE);<br>SetWindowLong(Handle, GWL_EXSTYLE, OldStyle Or WS_EX_TRANSPARENT);<br>因为此窗口不仅仅是半透明,操作也能透过该该窗口。<br><br>还有const<br>&nbsp; WS_EX_LAYERED = $80000; <br>&nbsp; WS_EX_TRANSPARENT = $20;<br>&nbsp; LWA_ALPHA = $2;<br>真的多余
 
谢谢<br>还想请问glacieret<br>OldStyle := GetWindowLong(Handle, GWL_EXSTYLE);//是不是得到改窗口扩展的窗口类型?<br>OldStyle := GetWindowLong(Handle, GWL_STYLE);//是不是得到传统的窗口类型?<br>有啥区别?两行代码都可以运行,只是出来的窗口界面不同。<br><br>还有GetWindowLong是啥意思?再次感谢两位<br><br>GWL_EXSTYLE Retrieves the extended window styles.<br>GWL_STYLE Retrieves the window styles.<br>
 
偶也想知道,在98下如何实现半透明的窗体呢??
 
函数功能:该函数改变指定窗口的属性.函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。<br><br>&nbsp; &nbsp; 函数原型:LONG SetWindowLong(HWND hWnd,int nlndex,LONG dwNewLong);<br><br>&nbsp; &nbsp; 参数:<br><br>&nbsp; &nbsp; hWnd:窗口句柄及间接给出的窗口所属的类。<br><br>&nbsp; &nbsp; nlndex:指定将设定的大于等于0的偏移值。有效值的范围从0到额外类的存储空间的字节数-4:例如若指定了12位或多于12位的额外类存储空间,则应设为第三个32位整数的索引位8。要设置其他任何值,可以指定下面值之一:<br><br>&nbsp; &nbsp; GWL_EXISTYLE:设定一个新的扩展风格。GWL_STYLE:设定一个新的窗口风格。<br><br>&nbsp; &nbsp; GWL_WNDPROC:为窗口过程设定一个新的地址。GWL_ID:设置一个新的窗口标识符。<br><br>&nbsp; &nbsp; GWL_HINSTANCE:设置一个新的应用程序事例句柄。<br><br>&nbsp; &nbsp; GWL_USERDATA:设置与窗口有关的32位值。每一个窗口均有一个由创建该窗口的应用程序使用的32位值。<br><br>&nbsp; &nbsp; 当hWnd参数标识了一个对话框时,也可使用下列值:<br><br>&nbsp; &nbsp; DWL_DLGPROC:设置对话框过程的新地址。<br><br>&nbsp; &nbsp; DWL_MSGRESULT:设置在对话框过程中处理的消息的返回值。<br><br>&nbsp; &nbsp; DWL_USER:设置的应用程序私有的新的额外信息,例如一个句柄或指针。<br><br>&nbsp; &nbsp; dwNewLong:指定的替换值。<br><br>&nbsp; &nbsp; 返回值:如果函数成功,返回值是指定的32位整数的原来的值。如果函数失败,返回值为0。若想获得更多错误信息,请调用GetLastError函数。<br><br>&nbsp; &nbsp; 如果指定32位整数的原来的值为0,并且函数成功,则返回值为0,但是函数并不清除最后的错误信息,这就很难判断函数是否成功。这时,就应在调用SetWindowLong之前调用callingSetLastError(0)函数来清除最后的错误信息。这样,如果函数失败就会返回0,并且GetLastError。也返回一个非零值。<br><br>&nbsp; &nbsp; 备注;如果由hWnd参数指定的窗口与调用线程不属于同一进程,将导致SetWindowLong函数失败。<br><br>&nbsp; &nbsp; 指定的窗口数据是在缓存中保存的,因此在调用SetWindowLong之后再调用SetWindowPos函数才能使SetWindowLong函数所作的改变生效。<br><br>&nbsp; &nbsp; 如果使用带GWL_WNDPROC索引值的SetWindowLong函数替换窗口过程,则该窗口过程必须与WindowProccallback函数说明部分指定的指导行一致。<br><br>&nbsp; &nbsp; 如果使用带DWL_MSGRESULT索引值的SetWindowLong函数来设置由一个对话框过程处理的消息的返回值,应在此后立即返回TRUE。否则,如果又调用了其他函数而使对话框过程接收到一个窗口消息,则嵌套的窗口消息可能改写使用DWL_MSGRESULT设定的返回值。<br><br>&nbsp; &nbsp; 可以使用带GWL_WNDPROC索引值的SetWindowLong函数创建一个窗口类的子类,该窗口类是用于创建该窗口的关。一个应用程序可以一个系统美为于类,但是不能以一个其他进程产生的窗口类为子类,SetwindowLong函数通过改变与一个特殊的窗口类相联系的窗口过程来创建窗口子类,从而使系统调用新的窗口过程而不是以前定义的窗口过程。应用程序必须通过调用CallWindowProc函数向前窗口传递未被新窗口处理的消息,这样作允许应用程序创建一个窗口过程链。<br><br>&nbsp; &nbsp; 通过使用函数RegisterClassEx将结构WNDCLASSEX中的cbWndExtra单元指定为一个非0值来保留新外窗口内存。<br><br>&nbsp; &nbsp; 不能通过调用带GWL_HWNDPARENT索引值的SetWindowLong的函数来改变子窗口的父窗口,应使用SetParent函数。<br><br>&nbsp; &nbsp; Windows CE:nlndex参数必须是4个字节的倍数不支持unaligned access。<br><br>&nbsp; &nbsp; 不支持下列nlndex参数值:。<br><br>&nbsp; &nbsp; GWL_HINSTANCE;GWL_HWNDPARENTGWL;GWL_USERDATA<br><br>&nbsp; &nbsp; Windows CE 2.0版支持在nlndex参数中的DWL_DLGPROC值,但是WindowsCE1.0不支持。<br><br>&nbsp; &nbsp; 速查:Windows NT:3.1以上版本;Windows:95以上版本;Windows CE:1.0以上版本:头文件:winuser.h;库文件:user32.lib;Unicode:在Windows NT上实现为Unicode和ANSI两种版本。<br><br>&nbsp; &nbsp; 函数功能:该函数删除一个窗口类,清空该类所需的内存。<br><br>&nbsp; &nbsp; 函数原型:BOOL UnRegisterClass(LPCTSTR IpClassName; HINSTANCE hlnstance);<br><br>&nbsp; &nbsp; 参数:<br><br>&nbsp; &nbsp; IpClassName:指向一个空结束字符串的指针,或是一个整型原子。如果IpClassName是一个字符串,则它指定了窗口类的类名。这个类名必须由此前调用RegisterClassEx函数来注册。系统类,如对话框控制,必须被注册。<br><br>&nbsp; &nbsp; 如果这个参数是一个整型原子,它必须是由此前调用GlobalAdd原子函数创建的全局原子。这个16位整型数小于OxCOOO,必须是lpszClass的低16位,其高位宇必须为0。<br><br>&nbsp; &nbsp; hlnstance:创建类的模块的事例句柄。<br><br>&nbsp; &nbsp; 返回值:如果函数成功,返回值为非零;如果未发现类或由此类创建的窗口仍然存在,则返回值为0。<br><br>&nbsp; &nbsp; 若想获得更多错误信息,请调用GetLastError函数。<br><br>&nbsp; &nbsp; 备注:在调用这个函数之前,应用程序必须销毁由指定类创建的所有窗口。<br><br>&nbsp; &nbsp; 应用程序注册的所有窗口类在应用程序中止后都为未注册的类。<br><br>&nbsp; &nbsp; Windows 95:所有由OLL注册的窗口类在DLL卸载后均未注册的类。<br><br>&nbsp; &nbsp; windows NT:所有由DLL注册的类在DLL卸载后仍为已注册的类。<br><br>&nbsp; &nbsp; 速查:Windows NT:3.1以上版本;Windows:95以上版本;Windows CE:1.0以上版本;头文件:winuser.h;库文件:user32.lib;Unicode:在Windows NT上实现为Uhicode和ANSI两种版本。<br><br>
 
后退
顶部