这个东西其实做个实验就可以知道.不过分析起来比较有意思.
CreateWindow Called
WM_CREATE
CreateWindow Return
Message Loop
在CreateWindow和Message Loop之间,可以调用相应的函数如ShowWindow, UpdateWindow.
其事件顺序是:
ShowWindow Called
WM_SIZE
ShowWindow Return
UpdateWindow Called
WM_PAINT
UpdateWindow Return
如果带有WS_VISIBLE的窗体,并不主动调用ShowWindow和UpdateWindow函数.则在Message Loop开始后,先调用 WM_SIZE,后调用WM_PAINT.
其实这些都很容易理解,不过使用的时候就有很多地方需要注意了.
比如我们经常将CreateWindow的返回值作为全局的变量.我们也会在WM_CREATE时调用一些初始化函数.
这些初始化函数需要的主窗口句柄就必须是WM_CREATE消息的,而不能是全局的那个.因为全局的那个还没有被正确地返回.
同样的道理.如果WM_SIZE和WM_PAINT都使用一些公共的变量,就要在WM_SIZE里面先准备好.也尽量不要主动调用WM_PAINT.否则难免出现变量混乱的局面.
Tuesday, January 27, 2009
Saturday, January 24, 2009
工具介绍 Control Spy 2.0
Control Spy是微软免费提供的一个小巧的工具.别的不说,先看截图.

如果你做过WIN32开发.可能你已经看出来了.这是一个用来测试Windows公共控件的工具.
微软的原话是Control Spy is a tool to help developers understand common controls.
公共控件(common controls)给人的感觉是虽然很普通,但是却很复杂.(这点用.NET编程的人我猜一般是不会体会到的,前几天一个学弟对我说"C#的按钮划过的事件怎么这么复杂啊...". –_-~~)
使用Control Spy可以几乎做到对控件的完全控制.包括Message, Notify.可以直接更改STYLE.
对应不熟悉控件消息的人来说这绝对是福音.
不过我使用的时候发现很多BUG,比如某些Style识别出错.有些STYLE不起效果.
我想这就是为什么他没有被加入到VS中的原因.
还有就是由于其自身设计的原因,有些东西是一辈子捕捉不到的.比如更改某些STYLE后重绘的XXX.还有窗体移动的消息....
一个简单的小例子,更改按钮文字.通过他至少知道参数是从LPARAM传进去的.

另外,通过它我终于明白了为什么Vista的控件有时候渐变得很干涩...
原来它是通过把原来一次解决的WM_PAINT事件一连调用16次来达到渐变...
以图为证.

PS:内部代号为BinPlayer的播放器进展缓慢.在家7天重构了3次.还是觉得不满意.核心功能没增加反而减少了...

如果你做过WIN32开发.可能你已经看出来了.这是一个用来测试Windows公共控件的工具.
微软的原话是Control Spy is a tool to help developers understand common controls.
公共控件(common controls)给人的感觉是虽然很普通,但是却很复杂.(这点用.NET编程的人我猜一般是不会体会到的,前几天一个学弟对我说"C#的按钮划过的事件怎么这么复杂啊...". –_-~~)
使用Control Spy可以几乎做到对控件的完全控制.包括Message, Notify.可以直接更改STYLE.
对应不熟悉控件消息的人来说这绝对是福音.
不过我使用的时候发现很多BUG,比如某些Style识别出错.有些STYLE不起效果.
我想这就是为什么他没有被加入到VS中的原因.
还有就是由于其自身设计的原因,有些东西是一辈子捕捉不到的.比如更改某些STYLE后重绘的XXX.还有窗体移动的消息....
一个简单的小例子,更改按钮文字.通过他至少知道参数是从LPARAM传进去的.

另外,通过它我终于明白了为什么Vista的控件有时候渐变得很干涩...
原来它是通过把原来一次解决的WM_PAINT事件一连调用16次来达到渐变...
以图为证.

PS:内部代号为BinPlayer的播放器进展缓慢.在家7天重构了3次.还是觉得不满意.核心功能没增加反而减少了...
Windows API 手动载入 动态连接库 (.dll, .ax等) 运行其函数
自己编程一般不会用到这个.
大多数可以编程的库都提供文档,头文件,lib等文件.
不过有些是不提供的.活生生只给你一个dll.
不过这时候如果知道里面函数的名字和参数啥的,就可以调用.
以ax为例,ax后缀的一般是解码器的Filter.编写过filter的都知道,其实他就是一个DLL,有些解码器就是以dll作为后缀的.
现在:我要载入RealMediaSplitter.ax这个连接库,并且运行DllRegisterServer这个无参函数.
这里仅给出一个样例.核心就是使用LoadLibrary和GetProcAddress函数,用了一个typedef来使其看起来像模像样.
测试结果OK.其效果等价于在终端运行regsvr32 RealMediaSplitter.ax, 但是不是绿色载入, 以后会介绍一种绿色载入的方法, 那种方法在BinPlayer中被采用, 非常安全.
大多数可以编程的库都提供文档,头文件,lib等文件.
不过有些是不提供的.活生生只给你一个dll.
不过这时候如果知道里面函数的名字和参数啥的,就可以调用.
以ax为例,ax后缀的一般是解码器的Filter.编写过filter的都知道,其实他就是一个DLL,有些解码器就是以dll作为后缀的.
现在:我要载入RealMediaSplitter.ax这个连接库,并且运行DllRegisterServer这个无参函数.
这里仅给出一个样例.核心就是使用LoadLibrary和GetProcAddress函数,用了一个typedef来使其看起来像模像样.
if(HMODULE h = LoadLibrary(TEXT("RealMediaSplitter.ax"))) {
typedef HRESULT (__stdcall * PDllRegisterServer)();
if (PDllRegisterServer p = (PDllRegisterServer)GetProcAddress(h, "DllRegisterServer")) {
p();
}
FreeLibrary(h);
}
测试结果OK.其效果等价于在终端运行regsvr32 RealMediaSplitter.ax, 但是不是绿色载入, 以后会介绍一种绿色载入的方法, 那种方法在BinPlayer中被采用, 非常安全.
Wednesday, January 21, 2009
DirectShow 之 自定义视频窗口
DirectShow在播放视频时,默认会蹦出一个视频窗口来.
貌似我们不能让他在指定的窗体中播放,那我们可以把他放在其他窗体中,作为子窗体.
IVideoWindow::put_Owner似乎是可以用的方法,但是它却又一些注意点和技巧.有些是MSDN没有提及的:
1. put_Owner方法必须在Stream流已经生存的情况下才能使用.一般在IGraphBuilder::RenderFile和IGraphBuilder::Run之间比较合适.
2. 利用IVideoWindow::put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);来让窗体看上去像是一个播放器的视频部分.当然还有IVideoWindow::SetWindowPosition方法
3. 在Filter Graph Manager的Release之前put_Owner为NULL.不然会很惨...(会给代替带来N多垃圾消息,详见MSDN)
貌似我们不能让他在指定的窗体中播放,那我们可以把他放在其他窗体中,作为子窗体.
IVideoWindow::put_Owner似乎是可以用的方法,但是它却又一些注意点和技巧.有些是MSDN没有提及的:
1. put_Owner方法必须在Stream流已经生存的情况下才能使用.一般在IGraphBuilder::RenderFile和IGraphBuilder::Run之间比较合适.
2. 利用IVideoWindow::put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);来让窗体看上去像是一个播放器的视频部分.当然还有IVideoWindow::SetWindowPosition方法
3. 在Filter Graph Manager的Release之前put_Owner为NULL.不然会很惨...(会给代替带来N多垃圾消息,详见MSDN)
高清电影中出现人声过小的问题的原因和解决
现象:用某些播放器播放电影时,出现背景声音非常大,人声非常小的问题.
这种问题在高清格式的电影上出现频率较高.
原因:正常的音频是双声道的.就是普通的立体声.比如大家常听的普通MP3.
事实上音频可以是多声道的.比如3~6个声道都是有可能的.高清格式为了保证音频的高质量,也通常采用多声道压缩.
比如AC3一般有6声道,DTS一般为5声道.
这些声道有中间声道和两边声道之分.一般中间声道担负的主要的人声(其他声道也有,不过主要做辅助用)
通常来说,电脑中的播放器播放多声道音频时,会把多声道转化为双声道.
但是有些播放器没有这么做.比如KMPlayer.结果只播放了两边声道.
解决:手动配置,使其将中间声道也混入两边声道.
这种问题在高清格式的电影上出现频率较高.
原因:正常的音频是双声道的.就是普通的立体声.比如大家常听的普通MP3.
事实上音频可以是多声道的.比如3~6个声道都是有可能的.高清格式为了保证音频的高质量,也通常采用多声道压缩.
比如AC3一般有6声道,DTS一般为5声道.
这些声道有中间声道和两边声道之分.一般中间声道担负的主要的人声(其他声道也有,不过主要做辅助用)
通常来说,电脑中的播放器播放多声道音频时,会把多声道转化为双声道.
但是有些播放器没有这么做.比如KMPlayer.结果只播放了两边声道.
解决:手动配置,使其将中间声道也混入两边声道.

Saturday, January 3, 2009
工具介绍 Microsoft Spy++
这是一个Visual Studio自带的工具. 这个工具什么时候有用呢?主要两种情况
1.编写要操作其他程序的程序.
2.是想观察其他程序的窗口属性,分析它是怎么实现的.

以前在不熟悉windows操作系统结构的时候,想编写一些操作系统辅助程序,老是遇到一些奇奇怪怪的问题.
时间长了之后才明白Windows的窗体结构...是一棵树..
然而从这里就可以一目了然地看出来.
还可以查看窗体的STYLE和CLASS,不过这个程序还是有些问题的.STYLE可能显示不标准.尤其是组件的STYLE.

最上面的图中, 灰色的图标表示不可见的Window,蓝色的是可见Window(包括最小化的啥的..)
窗体太多,想判断哪个对应哪个不太容易, 最基础的方式是看名称.
对于有些窗体,可以使用窗体高亮的功能:

最绝的是打开窗体属性,看窗体位置...,哈哈,这个基本上是无误的.

同时它还可以查看各个进程和线程的属性的功能, 使用一下, 还是很实用的.
1.编写要操作其他程序的程序.
2.是想观察其他程序的窗口属性,分析它是怎么实现的.

以前在不熟悉windows操作系统结构的时候,想编写一些操作系统辅助程序,老是遇到一些奇奇怪怪的问题.
时间长了之后才明白Windows的窗体结构...是一棵树..
然而从这里就可以一目了然地看出来.
还可以查看窗体的STYLE和CLASS,不过这个程序还是有些问题的.STYLE可能显示不标准.尤其是组件的STYLE.


最上面的图中, 灰色的图标表示不可见的Window,蓝色的是可见Window(包括最小化的啥的..)
窗体太多,想判断哪个对应哪个不太容易, 最基础的方式是看名称.
对于有些窗体,可以使用窗体高亮的功能:

最绝的是打开窗体属性,看窗体位置...,哈哈,这个基本上是无误的.

同时它还可以查看各个进程和线程的属性的功能, 使用一下, 还是很实用的.

Subscribe to:
Posts (Atom)