65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 示例代码/文章:扩展 C# (.NET) 中 GDI+ 的功能 - 第 III 部分

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (2投票s)

2008年7月13日

CPOL

2分钟阅读

viewsIcon

24039

downloadIcon

255

一篇关于 C# 示例代码/文章扩展 C# (.NET) 中 GDI+ 功能的文章

图 1

引言

在这里,作为我上一篇文章的延续,我介绍了另一种选择图像部分的方法。 就像我上一篇文章中的方法 2一样,用户不必担心选择矩形的调整大小/移动问题,因为这些将由选择窗口(也就是 Win32 窗口)处理。

这里采用的方法是,我在子窗体的窗口过程中捕获WM_EXITSIZEMOVE消息。 之前在主窗体中,我重写了OnLoad(…)方法并创建了另一个窗体,我们称之为类似子窗体的窗体(因为它几乎像主窗体的子窗体一样运行)并将它的所有者设置为我的主窗体。 见图 1。

protected override void OnLoad(EventArgs e)
{
      chFrm = new ChildForm();
      chFrm.Owner = this;
      chFrm.Show();
      chFrm.Location = new Point(Location.X + 50, Location.Y + 50);
      base.OnLoad(e);
}

现在类似子窗体的当前父窗体是桌面窗口,因此它变得透明(透明性在其客户区中体现),因为它现在等同于一个弹出窗口。 当用户尝试移动类似子窗体的窗体时,我快速做了两件事

  1. 将其父窗体从桌面窗口更改为主窗体
  2. 通过SetWindowLong(…) Win32 API 删除其WS_EX_LAYERED属性

这确保了类似子窗体的窗体永远不会离开主窗体。 当用户停止上述操作时,我只需要反向操作即可。

注意:为了获取桌面窗口的句柄,我使用 Win32 API,如下所示,通过pInvoke

[DllImport("user32.dll")]
static extern IntPtr GetDesktopWindow();

由于我们知道如果一个窗体成为子窗体,我们不能在其上应用SetLayeredWindowAttributes (…) API。 那么子窗体是如何仍然变得透明的呢? 输入子窗体的WM_EXITSIZEMOVE消息。 在退出移动或调整大小的模式循环后,WM_EXITSIZEMOVE消息会被发送到窗口一次。 所以要像上面说的那样反向操作,我快速再做两件事

  1. 切换子窗体的父窗体;从主窗体到桌面窗口
  2. 切换其分层属性,即我将WS_EX_LAYERED属性添加回子窗体

以上两件事帮助子窗体重获透明性,从而使用户能够看到其客户区。

下面显示了 Win32-API 设置透明度,即

[DllImport ("user32.dll")]
public static extern long SetLayeredWindowAttributes
    (IntPtr Handle, int Clr, byte transparency, int clrkey);

第四个参数int clrKey是键,在调用此 API 时,我为clrKey参数指定一种特定颜色,然后我用相同的颜色绘制类似子窗体的窗体。 这将在窗体的客户区创建一个孔。

注意:每当窗体更改其父窗体时,它也会根据其当前父窗体重新定位自身,基于其在WM_NCLBUTTONDOWNWM_EXITSIZEMOVE消息中的先前相对位置更改其位置,这可以防止这种不希望的位置更改。

历史

  • 2008 年 7 月 11 日:初始版本
© . All rights reserved.