WPF与Win32互操作
一、WPF如何使用HWND
当您创建WPF Window时,WPF会创建顶级HWND,并使用HwndSource将Window及其WPF内容放入HWND中。应用程序中其余的WPF内容共享此单个HWND。不过,菜单、组合框下拉列表和其他弹出窗口例外。 这些元素创建它们自己的顶级窗口,这正是 WPF 菜单能跳出包含它的窗口 HWND 之外的原因。
二、HwndSource类
一个HwndSource实现Win32窗口可以包含WPF内容。在窗口中的WPF内容是可安排的,可测量的,和可渲染的;是可交互式输入的。因为HwndSource是专被设计来与Win32进行交互的,这个类展示了底层的Win32的特点。您可以使用这个类执行以下操作:
- 指定窗口样式、窗口类样式和扩展窗口样式。
- 在窗口程序的钩子中添加处理函数。
- 提供窗口句柄(HWND)。
- 销毁窗口。
HwndSource类被设计来用于处理一般的互操作,并不是被设计成一个包装管理HWND的角色。一般来说,它不提供用于管理窗口或检查属性状态的托管方法。相反,该HwndSource类可以通过Handle属性访问Win32窗口句柄(HWND),可以通过PInvoke Win32 API技术操作窗口。
1 创建
HwndSource只能在构造时被指定。创建一个HwndSource,首先要创建一个HwndSourceParameters结构并用所需的参数填充它。这些参数包括以下内容:
- 类、窗口和扩展的窗口样式。您必须在窗口被创建前使用PInvoke去改变样式。并非所有样式都可以在创建窗口后更改。更改窗口样式之前请参考win32文档。
- 窗口的初始位置。
- 窗口的初始大小,包括是否指定尺寸或以WPF内容大小的确定窗口的大小。
- 父窗口。
- HwndSourceHook包括窗口的处理函数链。如果在构建时指定钩子,它将接收窗口的所有消息。你可以使用AddHook后创建窗口添加一个钩子。
- 透明度设置。
2 对象生存周期
HwndSource是正规的公共语言运行库(CLR)对象,其生命周期是由垃圾收集器管理。因为HwndSource代表非托管资源,所以HwndSource实现IDisposable接口。如果从所有者线程调用,同步调用处理立即破坏win32窗口。如果从另一个线程调用,win32窗口将异步销毁。在互操作的代码中显式调用Dispose可能对某些互操作场景是必要的。
3 窗口处理函数
HwndSource类实现了它自己的窗口处理函数。此窗口处理函数用于处理重要的窗口消息,如与布局、呈现和输入相关的消息。不过,您也可以在钩子上添加自己的处理函数。你可以在构造时,通过设置HwndSourceParameters.HwndSourceHook属性,在钩子中指定自己的处理函数,或者你也可以使用AddHook和RemoveHook在窗口创建之后添加和删除钩子中的处理函数。
三、HwndSource类
该例子中在钩子中扩展处理函数。
// 在Window类中
protected overried void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
// 获取窗体句柄
IntPtr hwnd = new WindowInteropHelper(this).Handle;
// 获取HwndSource对象
HwndSource hwndSource = HwndSource.FromHwnd(hwnd);
// 向钩子中添加处理程序
if(hwndSource != null)
hwndSource.AddHook(WndProc);
} private IntPtr WndProc(IntPtr hWnd, int msg, IntPtr wideParam, IntPtr longParam, ref bool handled)
{
swicth(msg)
{
// 对特定消息进行处理
}
return IntPtr.Zero;
}
WPF与Win32互操作的更多相关文章
- WPF.UIShell UIFramework之自定义窗口的深度技术 - 模态闪动(Blink)、窗口四边拖拽支持(WmNCHitTest)、自定义最大化位置和大小(WmGetMinMaxInfo)
无论是在工作和学习中使用WPF时,我们通常都会接触到CustomControl,今天我们就CustomWindow之后的一些边角技术进行探讨和剖析. 窗口(对话框)模态闪动(Blink) 自定义窗口的 ...
- WPF实现毛玻璃效果
1和2需要Microsoft.WindowsAPICodePack.Shell.dll 和引用using System.Windows.Interop,并只能在有DwmApi.dll 版本的Windo ...
- WPF 4.5 is here : check out the new features !
So what's New in WPF Version 4.5 Developer Preview ? Here is a list of the new features and their re ...
- 【转】WPF的知识
[-] 闲话WPF之二XAML概述 闲话WPF之五XAML中的类型转换 闲话WPF之十六WPF中的资源 2 闲话WPF之十九WPF中的传递事件 1 闲话WPF之二十WPF中的传递事件 2 闲话WPF之 ...
- WPF中,如何将Vista Aero效果扩展到整个窗口
原文:WPF中,如何将Vista Aero效果扩展到整个窗口 WPF中,如何将Vista Aero效果扩展到整个窗口 ...
- VSTO之WPF和Winform弹窗
写插件弹窗是肯定要有的,有弹窗才有展示功能的页面啊! 记录一下前段时间遇到的一些弹窗方面的坑,一个个踩过来也是收获颇丰啊! WPF弹窗 最简单的弹窗方式,new一个窗体,然后调用Show方法. Win ...
- WPF 半透明 模糊效果 Aero效果(1)
先看看效果图 目前网上找到了2种实现方式,一种是 .NET Framework4.5及以后有自带的 WindowChrome 效果,一种是 WindowsAPI dwmapi.dll ,但这两种在 ...
- WPF 通过进程实现异常隔离的客户端
当 WPF 客户端需要实现插件系统的时候,一般可以基于容器或者进程来实现.如果需要对外部插件实现异常隔离,那么只能使用子进程来加载插件,这样插件如果抛出异常,也不会影响到主进程.WPF 元素无法跨进程 ...
- WinUI 3 踩坑记:前言
WinUI 3 (Windows App SDK 于 2021 年 11 月发布了第一个正式版 v1.0.0 [1],最新版本是 v1.1.5 [2].我的基于 WinUI 3 的个人项目 寻空 从年 ...
随机推荐
- SCOI 2010 序列操作
题目描述 lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 1 a b ...
- 关于 Python 入门的一些问题?
一.用 python 能够做什么?解决什么问题? A1:理论上来说,计算机能做什么,python 语言就能让它做什么,也即 python能做什么. 数值计算.机器学习.爬虫.云相关开发.自动化测试.运 ...
- javascript 之作用域链-10
前言 在<执行环境>文中说到,当JavaScript代码执行一段可执行代码时,会创建对应的执行上下文(execution context). 变量对象(Variable object,VO ...
- Javascript一句代码实现JS字符串去除重复字符
需求: 原字符串:abcdabecd 去重后字符串:abcde JS字符串去重,一个简单需求,网上找案例发现都是一大堆代码,对于强迫症的我 实再无法忍受,于是自己手动写出一段代码,完美解决该问题. 代 ...
- 那些年原生js实现的楼层跳转
最近做一个需求~~楼层跳转(京东.淘宝侧边导航),由于现在项目都用框架,所以 jquery是不能再用了,只好自己原生写一个,其实实现起来很简单,无非就是获取到每个楼层距离文档顶部的距离,然后通过控制滚 ...
- C# ASP.NET 转换为int型的方法 很实用
很多新手在搞c#或者.net开发的时候总会碰到一些小问题,如何知道字符能不能为int型 在这里我写了一个小的函数仅供大家参考: /// <summary> /// 判断是不是int型 / ...
- centos设置程序开机自启或禁止加载
1. 可以直接把需要启动的脚本写到/etc/rc.d/rc.local文件里,例如 vim /etc/rc.d/rc.local /usr/local/apache/bin/apachectl sta ...
- 使用JavaScript 操作本地文件
一.显示用户选择文件[图片] <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- 【转载】vim复制时的缩进
:set paste vi/vim鼠标中键粘贴文本默认情况是自动缩进的,如果粘贴的是多行的文本,则第二行缩进1个tab,第三行缩进2个tab……依此类推,到最后文本会面目全非,解决办法是粘贴之前设置为 ...
- Jmeter发送JDBC请求
下午花了两个小时研究了一下Jmeter发送JDBC请求,现在把基本操作流程分享一下. 做JDBC请求,首先需要两个jar包:mysql驱动-mysql-connector-java-5.1.13-bi ...