关于画非客户,其实在VC中已有相关的许多资料,而C#的也有,只是不全面。因为用C#做WINFORM的本来就不是特别多,有的也就加个皮肤控件就完事了。

可我有兴趣,终于完成了一个,嘿嘿!

其实画非客户并不难,只是处理的消息比较多,而C#调用API又不方便,或者说思路就没往API那方面去想,所以造成还是有点不适应。一直鄙視自已對API不是很熟,用到查到。。。。。

主要参考资料,都是VC的

http://www.3800hk.com/Article/cxsj/vc/jmlbcvc/2005-08-25/Article_54021.html

http://hi.baidu.com/ljfblog/blog/item/dc3d1a55c1ff35c6b745ae92.html

http://blog.csdn.net/yyan/archive/2007/04/06/1554048.aspx

主要处理的消息就是NC****,也即是NO CLIENT,所谓的非客户区。

主要处理的消息:

WM_NCCALCSIZE:

The WM_NCCALCSIZE message is sent when the size and position of a window's client area must be calculated. By processing this message, an application can control the content of the window's client area when the size or position of the window changes.

wParam

If wParam is TRUE, it specifies that the application should indicate which part of the client area contains valid information. The system copies the valid information to the specified area within the new client area.

If wParam is FALSE, the application does not need to indicate the valid part of the client area.

lParam

If wParam is TRUE, lParam points to an NCCALCSIZE_PARAMS structure that contains information an application can use to calculate the new size and position of the client rectangle.

If wParam is FALSE, lParam points to a RECT structure. On entry, the structure contains the proposed window rectangle for the window. On exit, the structure should contain the screen coordinates of the corresponding window client area.

if (Convert.ToBoolean(m.WParam.ToInt32()))

{

Win32API.NCCALCSIZE_PARAMS t = (Win32API.NCCALCSIZE_PARAMS)m.GetLParam(typeof(Win32API.NCCALCSIZE_PARAMS));

//Win32API.NCCALCSIZE_PARAMS t = (Win32API.NCCALCSIZE_PARAMS)Marshal.PtrToStructure(m.LParam, typeof(Win32API.NCCALCSIZE_PARAMS));一直都用这个,后来才知消息参数里面就带了一个可以转的了

//        int i =Win32API.GetSystemMetrics(Win32API

//        .SM_CYCAPTION);

int CaptionHeight =

Win32API.GetSystemMetrics(Win32API

.SM_CYCAPTION);

int Border3DWidth = System.Windows.Forms.SystemInformation.Border3DSize.Width;

这里使用FW或者API都可以取到窗体的相关属性

int BorderWidth = System.Windows.Forms.SystemInformation.BorderSize.Width;

尝试过了,只有修改RECT[0]才有效果撒…

t.rgrc[0].top = t.rgrc[0].top - CaptionHeight - Border3DWidth - BorderWidth + TitleImageSize.Height - 1;设置标题栏高度为TitleImageSize.Height

t.rgrc[0].left = t.rgrc[0].left - Border3DWidth;

t.rgrc[0].right = t.rgrc[0].right + Border3DWidth;

t.rgrc[0].bottom = t.rgrc[0].bottom + Border3DWidth;

Marshal.StructureToPtr(t, m.LParam, false);结构体转指针

base.WndProc(ref m);

}

此消息是用于修改窗体客户区位置的。

WM_NCPAINT

The WM_NCPAINT message is sent to a window when its frame must be painted. An application can intercept the WM_NCPAINT message and paint its own custom window frame. The clipping region for a window is always rectangular, even if the shape of the frame is altered.

关健就在于怎么取于DC,不过在FW之下这一下是这么简单

IntPtr hDC = Win32API.GetWindowDC(m.HWnd);

Bitmap bmp = new Bitmap(TitleRec.Width, TitleRec.Height);

Graphics gBMP = Graphics.FromImage(bmp);

Graphics gs = Graphics.FromHdc(hDC);

MSDN示例:

case WM_NCPAINT:
{
HDC hdc;
hdc = GetDCEx(hwnd, (HRGN)wParam, DCX_WINDOW|DCX_INTERSECTRGN);
// Paint into this DC
ReleaseDC(hwnd, hdc);
}
 
简单介绍下GetWindowDC

GetWindowDC

The GetWindowDC function retrieves the device context (DC) for the entire window, including title bar, menus, and scroll bars.

A window device context permits painting anywhere in a window,

because the origin of the device context is the upper-left corner of the window instead of the client area.

WM_NCHITTEST

The WM_NCHITTEST message is sent to a window when the cursor moves, or when a mouse button is pressed or released. If the mouse is not captured, the message is sent to the window beneath the cursor. Otherwise, the message is sent to the window that has captured the mouse.

把这消息处理了,那窗体点击会出现默认按钮,最大化最小化关闭按钮等问题就都解决了。

if (!IsMax)

if (NonCamandRectange.Contains(CurPoint))

{

m.Result = (IntPtr)Win32API.HTCAPTION;

}

还有下面这两个消息

WM_NCUAHDRAWCAPTION

WM_NCUAHDRAWFRAME

這兩個消息好難才找到撒。。。。謝謝前面LJF的博文

“  0x00AE://WM_NCUAHDRAWCAPTION
    0x00AF://WM_NCUAHDRAWFRAME
 这两条消息是在xp sp2后加的.xp在以前有个bug在某些时候Titlebar会画错.
在这里不能调用默认处理,直接自绘nc区.”

WM_ACTIVATEAPP

不知大家有沒注意到,有時窗口獲取焦點時標題欄大小會變一點點。而窗體獲得焦點或失去焦點都會發送這個消息,只是在WParam裡面說明是獲得還是失去焦點.ONLostFoucs等都用。

The WM_ACTIVATEAPP message is sent when a window belonging to a different application than the active window is about to be activated. The message is sent to the application whose window is being activated and to the application whose window is being deactivated.

wParam

Specifies whether the window is being activated or deactivated. This parameter is TRUE if the window is being activated; it is FALSE if the window is being deactivated

处理以下消息,可以

WM_NCLBUTTONUP

WM_NCLBUTTONDOWN

WM_NCMOUSEMOVE

這幾倏消息就不難了。。。。處理下就可以了。嘿嘿,主要還是在繪制按鈕上。剩下就是圖片。

转载于:https://www.cnblogs.com/yellowyu/archive/2009/03/27/1423733.html

winform:關於画非客户区相关推荐

  1. 【转】 VC MFC 钩子 实现 自绘 窗体 标题栏 非客户区

    效果: 程序: #if !defined(_LJF_LJFHOOK_H) #define _LJF_LJFHOOK_H #if _MSC_VER > 1000 #pragma once #end ...

  2. VC 实现 自绘 窗体 标题栏 非客户区

    转载自 ljfblog 最终编辑 gh0716 本程序在VC03测试成功,效果, 图片素材:从BC1.bmp到第2页的UR_N.bmp ■■更新■■ 彻底解决最大最小关闭按钮依然显示的问题: 在Win ...

  3. 開博客了, 因為搞Delphi 開發的關於Delphi學習

    開博客了, 因為搞Delphi 開發的關於Delphi學習,之前都是用本地TXT文件保存,發現在本地電腦保存非常不方面,而且只能在一台電腦上保存,不容易查看和修改內容.便於以後的記錄只用,以及經驗交流 ...

  4. 令人费解的MFC客户区

    估计很多人都会遇到这么一个问题,平时我们用单文档/视图结构时,很容易就在客户区画个图,画根线什么的,然而,要在对话框的某个控件中画这些东西,刚一上来,还真有点搞吧. 下面,我就把在对话框中对某个控件画 ...

  5. 關於python 2.x中文字編碼的簡單說明

    關於python 2.x中文字編碼的簡單說明 關於python 2.x中文字編碼的簡單說明 from v2ex By 013231 at 2 天前, 154 次点击 剛剛看到有人在糾結文字編碼的問題, ...

  6. bitmap画文字 居中_画非画展览馆 观赏石 第八期拍卖

    展览馆介绍 画非画展览馆  经过近一年的扩建升级,第一期工程已初具规模,展览馆分为十个厅,已于2020年9月19日正式开馆.馆内将陈列展示来自世界各地的奇珍异石和各类高端艺术品.画非画展览馆诚邀有识之 ...

  7. infoseccrypto_java下载_關於php接ICBC的支付接口的解決方案

    一:背景: 目前項目使用的是php語言開發,需要接入中國工商銀行的ICBC的線上支付接口. 二:遇到的問題:支付時需要對數據簽名,但是銀行那邊不提供php版本的程序,只有java版本的,以下是對接人回 ...

  8. 關於微軟TTS的筆記

    目录 零.政策更新 2024年之後將不支持標準語音,建議大家更換下神經語音 一.扯皮TTS 先說環境: 支持的環境: SDK模式: 引入依賴 統一註冊事件 ①文本模式: ②SSML模式 ③關於解析器S ...

  9. r语言热图对列不进行聚类_R语言 Pheatmap 画非聚类 热图

    python pandas 加 R Pheatmap 画非聚类热图 最近需求一个需求图 f9cb530a4fb553c2f42fd8f157cd451.png 上面的annotation部分用作临床注 ...

  10. 關於如何更改戰地2_AIX2 Reality4.5模組人數上限且平衡的方法

    有夥伴不知道這個AIX2 Reality4.5模組的人數爲什麽調了ai文件夾中的aidefault.ai文件后人數不生效,要麽就是對面只有24個,我們這邊多得多, 這個原因很簡單,因爲這個模組的每張地 ...

最新文章

  1. 两台电脑之间用网线之间传文件
  2. 基于SSM实现租房平台管理系统
  3. 如何在 Janus 中获取 WebRTC 的流
  4. 基于直方图的图像增强算法(HE、CLAHE、Retinex)
  5. ajax 示例代码,Ajax的简单实用实例代码
  6. cass小插件集合_插件|如何精准提取CASS方格网高程点?
  7. php xssclean,php – Codeigniter xss_clean困境
  8. spark计算操作整理
  9. Dom4J__ZZ_我的示例代码
  10. 让div跟着鼠标移动
  11. 将 SharePoint 2010 网站集升级到 2013 (含沙盒方案)
  12. 解压rootfs.img根文件系统
  13. Chrome浏览器解决主页被劫持的问题
  14. BF2地图下载 战地系列非官方单机地图集
  15. linux运行getch吗,在linux中使用getch()函数
  16. 用 Python 实现哈希算法检测重复图片
  17. 配置teamviewer远程无显示器ubuntu工控机实操
  18. SQL注入漏洞-GET注入
  19. baked light+bake indirect+sampling lightmap
  20. 要想成为一名真正的程序员,有哪些要求呢

热门文章

  1. canvas 绘制贪吃蛇游戏 1
  2. Linux网络服务_dhcp服务和dhcp中继服务
  3. linux下expect环境安装以及简单脚本测试
  4. Oracle数据库sql 列转字符串行函数WMSYS.WM_CONCAT()
  5. bio、nio、aio及select、poll、epoll
  6. spring 获取postman上传的二进制文件
  7. sqlite3 小记
  8. 制作网页特效的基本步骤
  9. Java开发中学用eclipse code templates
  10. H5获取html标签