win32创建控件的一些问题
在我们使用CreateWindow();像一般控件建Windows扩展控件的时候我们会发现控件没有创建成功
这是因为我们没有对Windows扩展控件库进行初始化,这要我们使用InitCommonControlsEx();函数来对
Windows扩展控件库进行初始化,代码如下:
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(INITCOMMONCONTROLSEX);
InitCtrls.dwICC = ICC_PAGESCROLLER_CLASS; //这里填上你要用的扩展控件类
InitCommonControlsEx(&InitCtrls);
这样我们就可以成功创建扩展控件了。
另外对于需要调用扩展控件.dll的(MSDN里面有说明)
我们需要 HINSTANCE hInstRich = ::LoadLibrary(_T("Riched32.dll")); 加载DLL到实例句柄
hWndEditU = CreateWindowEx(NULL,L"RichEdit",L"显示",WS_CHILD|WS_VISIBLE|WS_BORDER|
ES_LEFT|ES_MULTILINE ,10,10,400,320,hWnd,NULL,hInstRich,NULL);
这样创建之后我们就可以调用出 扩展控件来进行编写了!
需要注意的是在我们使用完之后需要释放DLL的
::FreeLibrary(hInstRich);
问题描述:
采用Win32 SDK编程,主窗口显示采用DialogBox()函数,在窗口中添加了List control控件后,程序一运行就退出,删除List control控件后,程序就可以正常运行了。
解决过程:
调试发现,对话框中添加了list control后,DialogBox返回值为-1,然而GetLastError()返回值为0,在对话框的回调函数中的消息处理上添加断点,发现调用DialogBox()后已经进入消息循环。把List control删除后,程序也就能正常运行了,这是为何?唉,苦恼中……
解决办法:
在DialogBox()函数前添加InitCommonControls(); 同时别忘了添加#include <commctrl.h>哦!
知识扩展:
因为公共控件同操作系统核心是分离的,所以在使用任何一个公共控件前必须要初始化包含公共控件的DLL。在所有Windows版本里,也包括Windows CE,您可以调用void InitCommonControls(void)来装载动态库并注册许多公共控件类。该调用并不初始化日历控件、时间选择控件、up/down控件、IP地址控件以及其它更新一些的公共控件。要初始化这些控件,使用函数BOOL InitCommonControlsEx(LPINITCOMMONCONTROLSEX lpInitCtrls); 该函数允许应用程序只装载和初始化选择的公共控件。该函数在Windows CE下很容易获得,因为只装载需要的控件可以减少对内存的影响。该函数唯一的参数是一个含有两个域的结构,该结构有一个尺寸域和一个包含标志集的域,标志集用来指出哪些公共控件需要被注册。下表给出了可以使用的标志及对应的控件。
公共控件对应的标志
Flag |
Control Classes Initialized |
---|---|
ICC_BAR_CLASSES |
Toolbar |
Status bar |
|
Trackbar |
|
Command bar |
|
ICC_COOL_CLASSES |
Rebar |
ICC_DATE_CLASSES |
Date and time picker Month calendar control |
ICC_LISTVIEW_CLASSES |
List view |
ICC_PROGRESS_CLASS |
Progress bar control |
ICC_TAB_CLASSES |
Tab control |
ICC_TREEVIEW_CLASSES |
Tree view control |
ICC_UPDOWN_CLASS |
Up-Down control |
ICC_TOOLTIP_CLASSES |
Tool tip control |
ICC_CAPEDIT_CLASS |
Cap edit control |
一旦公共控件DLL被初始化,这些公共控件就可以像其它任何控件一样对待了。每个控件都有一个可定制风格标志集,用来配置控件的外观和行为。针对每个控件的消息会被发出,用来配置和操纵控件并让控件执行某些动作。标准Windows控件和公共控件之间的一个主要差别是事件通知或服务请求是通过WM_NOTIFY消息来发出,而标准控件则是通过WM_COMMAND消息发出的。同通过WM_COMMAND消息发出的通知相比,采用这种技术可以使通知能够包含更多的信息。另外,这种技术允许为每个使用该通知的控件进行扩展和改编WM_NOTIFY消息。
WM_NOTIFY消息在lParam参数中携带着指向NMHDR结构的指针,NMHDR定义如下:
typedef struct tagNMHDR {
HWND hwndFrom;
UINT idFrom;
UINT code;
} NMHDR;
hwndFrom是发送通知消息的窗口句柄。对属性页来说,就是属性页窗口。如果是控件发送通知的话,idFrom就是控件ID。最后一个code域包含的是通知码。同WM_COMMAND消息相比,虽然这个基本结构没有包含任何更多的信息,但它几乎总是可以扩展的,可以使用附加域来扩展它。通知码指出有什么样的附加域附加到了该通知结构里。
公共控件编程中另一个不同点是发给公共控件的大部分与控件相关的消息都有预定义的宏,用这些宏来发送消息,看上去像是应用程序在调用函数。所以不用像下面的语句那样使用LVM_INSERTITEM消息来给列表控件插入一个项,如
nIndex = (int) SendMessage (hwndLV, LVM_INSERTITEM, 0, (LPARAM)&lvi);
而是可以很容易地使用nIndex = ListView_InsertItem (hwndLV, &lvi)即可。
这两行语句没有功能上的差别。用宏地优势是清晰。宏和其它公共控件编程中需要的定义们一起都位于CommCtrl.h中。用这些宏的一个问题是编译器不能对参数执行类型检查,而假如宏是真正的函数的话是本应该执行的。这个问题也存在于SendMessage技术中,在SendMessage这种方式中参数必须是WPARAM和LPARAM类型,但消息缺乏类型检查也是比较常见的。总的来说,宏例程还是提供了更好的可读性。宏系统的一个例外是在命令条控件和命令带控件中进行宏调用的时候。在这些控件中,除了有大量的用宏包装的消息外,实际上还有许多真的函数。通常,我所说的消息是真正的消息,而不是它们对应的宏。这将有助于将消息或者宏同真正的函数区分开来。
参考文献:
<<Programming Microsoft Windows CE .NET, Third Edition>> byDouglas Boling
=================================================================================
win32 下为edit编辑框增加新的一行内容
::SendMessage(hWnd, EM_SETSEL, -1, -1);
::SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)lpszText);
win32创建控件的一些问题相关推荐
- Win32 ListBox控件
Win32 ListBox控件 创建ListBox控件 创建窗口函数 HWND CrateWindowEx(DWORD dwExStyle , // 窗口的扩展风格,基本没用LPCTSTR lpCla ...
- Win32公共控件 - 状态栏和工具栏
本篇是介绍公共控件系列文章的第2部分,描述了两种新的公共控件:状态栏和工具栏.本系列的其它文章涵盖了以下主题: 第1部分:基础 第3部分:滑动条.进度条和上下控件 第4部分:表头窗口和列表视图窗口 第 ...
- win32通用控件TreeView滚动条自绘
<标题>win32通用控件TreeView滚动条自绘 直接使用windows sdk 进行开发自绘滚动条是很让人蛋疼的,嫌消息HOOK 麻烦,又不了解第三方控件,别担心,你还有一条小路可走 ...
- C#线程间操作无效: 从不是创建控件 XX 的线程访问它
转自:http://www.arasplm.net/index.php/zh/community/myblog/c-xx-.html 前些天做的要使用到线程的项目,现在和大家分享一下感受! 以下面小列 ...
- 黄聪:BackGroundWorker解决“线程间操作无效: 从不是创建控件的线程访问它” (C# VS2008)...
在编程中经常会遇到在一个按钮中执行复杂操作,并将复杂操作最后返回的值加入一个ListView或ComboBox中候选.这个时候程序会卡,当程序员将这些卡代码放进线程(Thread)中后发现当对控件操作 ...
- 线程间操作无效: 从不是创建控件的线程访问它
转自原文 线程间操作无效: 从不是创建控件的线程访问它. using System; using System.Collections.Generic; using System.ComponentM ...
- 线程间操作无效:从不是创建控件的线程访问它的三种方法
访问 Windows 窗体控件本质上不是线程安全的.如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态.还可能出现其他与线程相关的 bug,包括争用情况和死锁.确保以线程安 ...
- 用委托在listbox中异步显示信息,解决线程间操作无效,从不是创建控件的线程访问它...
//创建一个委托,是为访问listbox控件服务的.public delegate void UpdateTxt(string msg);//定义一个委托变量public UpdateTxt upda ...
- asp.net 包含动态创建控件的容器如果要切换显示/隐藏不要用 Visible 属性
asp.net 包含动态创建控件的容器如果要切换显示/隐藏不要用 Visible 属性 就是不用 XXX.Visible = false; // true 因为这样该容器及其子控件会彻底的从页面上消 ...
最新文章
- 史上第一次,AI能够自学翻译地球上的任何语言了
- matlab 函数 向量参数,Scipy integrate(quad,quadration,nquad)不能集成向量参数化函数?等效函数(MATLAB works)...
- linux的nvme驱动需要关心的统计项
- kali Linux 安装
- AppStore发布产品步骤
- LeetCode刷题(9)
- 洛谷P1087 FBI树
- 【iCore1S 双核心板_ARM】例程五:IWDG看门狗实验——复位ARM
- 你的Redis集群撑得住吗?
- svg动画导致持续占用CPU
- mysql软件可行性分析报告_网上商城系统可行性分析报告.doc
- 数控加工仿真系统 - FANUC OI 车床编程笔记(粗略)
- 离线安装CDH5集群及相关软件
- webSocket和http长连接短连接
- 卸载并安装谷歌浏览器
- 什么是云计算,云计算的三种类型
- QQ文件七天未接收失效怎么办?QQ文件失效怎么恢复
- Unity3d组合键
- linux文件句柄上线的修改,修改Linux文件句柄限制
- centos 虚拟机输入大小写混乱问题