本篇主要解决上篇遗留的一些问题

先来回顾一下我们上次遗留的问题

  1. 消除图中不透明的地方
  2. 实现标题栏的拖动
  3. 实现窗体的最大化,最小化,关闭功能。

下面就来一个一个解决。

解决不透明的问题

首先为什么会有灰色的出现呢。不难想到这些灰色就是 Picturebox 的背景色。边角上的图片对粉红色透明了,但却露出了背景的颜色。知道了原因就好了解决了,就是我们需要将这一块的背景色给透明掉。有人说可以讲 picturebox 的背景色设置为透明的啊。不错,是可以,但整个窗体的背景色呢?picturebox 下面不还是有整个被覆盖的窗体的嘛!窗体是不能像用户控件那样背景色设置为透明的,不过却有一个属性 TransparencyKey 可以间接的为我们解决这个问题。这个属性的作用是这样的,当这个属性设置为某一种颜色后,那该窗体上的所有的这种颜色将都变为透明色。

所以我们只需将 TransparencyKey 的颜色和窗体的背景色设置成一样,那么背景色不就自动透明了嘛!在这里我们将所有控件的背景色和 TransparencyKey 都设置成系统里面的 Info 颜色(这个颜色你可以自己指定,不过不建议是原来的 Control 色,因为这样后你再添加一个普通的控件,那么这个控件的一部分也会被透明掉)

实现标题栏的拖动

因为我们的窗体是没有状态栏的,所以当我们想移动窗口的时候发现怎么也”移不动”(不是有个笑话的嘛“中国移不动“,呵呵)。要解决这个问题还是需要借助 API 来完成。那如何知道别人需要移动窗体呢?这里我们就通过 MouseDown 这个事件来判断。即如果用户在特定的区域内按下了鼠标左键,那么我们就认为用户需要移动客户端了。这个时候我们调用相应的 API 向系统通知(SendMessage)让系统做出响应。为了效果好一点,我们将状态栏那一行的所有的 MouseDown 事件都用这个方法。于是现在我们运行一下看看能否移动窗体。

很不错嘛!又是一个问题解决了,现在只要将右上方的三个按钮的功能完成那这个窗体就算基本完成了啦。好了,我们继续。

要处理按钮的事件,毫无疑问我们在设计模式中双击对应的按钮,然后处理。这里还要提一下的就是我们需要在这些事件的每个方法钱加一个 virtual 让这些个方法可以被重写。道理很简单,假如我按关闭按钮的时候不想其直接关闭而是先弹出对话框提醒一下用户怎么办呢?总不能让用这个控件的人再去修改这个皮肤控件吧,最好的办法就是可以让他们重写按钮的 click 事件,他们想干嘛干嘛,不想有其他的功能只要不重写就是了。

好了开始说最小化功能吧

很简单,一句话搞定:this.WindowState = FormWindowState.Minimized;然后是关闭按钮,还是一句话的事情:this.close();呵呵貌似这两个功能真简单那!原本最大化也不复杂的,可是遇到了前面说到的那个问题,我们就知道想点儿其他的办法啦。看代码:

当用户点击最大化按钮的时候我们先将最大化按钮上移隐藏,然后将还原按钮降下(还记得我们一开始给他设置的位置是-30 吗?),然后我们最大化之前就先记录窗体的大小和位置(就是最开始赋值的那四句话)信息便于后面的还原。接下来的四句就是咱们手动来制造一种窗体最大化的状态啦,首先位置肯定在左上角。然后大小应该就是用户电脑屏幕客户区的大小,这个大小我是用 Screen.PrimaryScreen.WorkingArea 这个函数得到的。状态设置完了我们只要改一下窗体的状态标识 st 为 stat.Max。然后当用户想还原的时候我们只要在 btres 的 click 的点击事件中做一下刚才那个动作的反就行了。怎么样,是不是也不难啊!Ok,最后看一下运行效果:

发现问题:

终于是做好了。不过假如你也实际跟我动手做出了一个,你或许会发现以下一些问题:

  1. 点击最大化的时候反应好像有点慢,意思就是大概要过个这个半秒钟才会最大化。
  2. 还有一个问题就是从最小化状态下恢复到最大化状态,窗体左上角会有闪烁现象(闪的实在太快了,没办法截图啊,大家可以应用下我下面上传的 DLL 运行下就知道了)。我们本来就是想美化窗口,但是如果这些个问题一来实在是给人感觉不好,甚至还不如不美化。在下一篇中我将会带领大家解决这个问题。
  3. 我们的窗体位置虽然能移动了,不过大小还不能拖动。

在下一篇中我会带领大家解决这些问题,敬请期待!