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

Header control

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创建控件的一些问题,码迷,mamicode.com

时间: 2024-08-24 14:59:13

win32创建控件的一些问题的相关文章

【转】Win32 创建控件风格不是Win XP解决方案

有时候我有在用Win32 API来向窗体上添加控件时,通过CreateWindow或CreateWindowEx创建出来的控件的风格不像XP风格,而是像Windows 2000的风格,界面很难看.注意,是动态调用CreateWindow来创建控件,不是从资源中加载. 这种情况下,我们怎么办呢,通常说来,造成这种情况都是由于没有正确加载资源,我们知道,像button, combobox, listbox等这些控件都是放在comctl32这个DLL里面的,所以有时候在用这些系统自定义的控件时,需要我

关于“线程间操作无效: 从不是创建控件’textBox1‘的线程访问它”异常的解决方法

线程间操作无效: 从不是创建控件“textBox1”的线程访问它 背景:通过一个辅助线程计算出的一个值赋给textBox1.text;解决办法:1.直接在窗体的构造函数中加:System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; 此时把所有的控件 合法性线程检查全部都给禁止掉了. 2.通过代理来解决(msdn) private delegate void SetTextCallback(string text);

026-代码创建控件-iOS笔记

学习目标 1.[理解]代码创建控件过程 2.[理解]代码实现QQ登陆界面 3.[理解]图片浏览器 4.[理解]汤姆猫小游戏 一.代码创建控件过程 所有控件都是类的对象,不同的类创建可以不同类型的控件.也是就说创建一个控件其实就是创建一个对应类的对象. 常用控件类型 UIButton:按钮,界面上可点击的大都是按钮 UILabel:标签,界面上只显示文字不能点击大都是标签 UITextField:文本框,界面上可输入数据的文本框 UIImageView:图片框,界面上不可点击的图片大都是图片框 使

线程间操作无效: 从不是创建控件“button1”的线程访问它。

.net2后是不能跨线程访问控件的.,窗体上的控件是当前主线程创建的,当用户异步执行一个方法:在该方法中给窗体上的控件赋值,记住:当执行一个异步委托的时候,其实 就是开了一个线程去执行那个方法,这样就会报错:线程间操作无效: 从不是创建控件“某某某”的线程访问它. C# WinForm开 发中,这是一个比较常见的异常:线程间操作无效,从不是创建控件“xxx”的线程访问它.这个异常来源于.NET2的一个限制:工作线程不能访问窗口线程 创建的控件.解决方法主要有两种,一种是在窗口线程中设置Check

线程间操作无效: 从不是创建控件“控件id”的线程访问它。(.net跨线程执行方法)

找了好久资料,终于解决了,特此记录下来. 1 delegate void DelListHandler(string number); /// <summary> /// 按标识删除listview内容 /// </summary> /// <param name="number">标识</param> private void DelListViewLog(string number) { for (int i = 0; i <

动态创建控件 #Create(...)

1.在类中创建一个控件对象;例:CButton m_btn;2.用Create创建一个对象(#其实已经与其绑定)m_btn.Create(.....); #注意Create()函数的参数3. #这是动态创建控件的一种方法....

swift 字符转为类,代码创建控件

在使用类之前要先获得 命名空间 通过json来获取 字符型的类名 然后创建类对象,这时候就要用到字符转类 // 从info字典中获取到 命名空间 转为字符型 let NS = NSBundle.mainBundle().infoDictionary!["CFBundleExecutable"] as! string let clss:AnyClass? = NSClassFormString(NS +"."+字符类名) let Vcla = clas as! UIV

线程间操作无效:从不是创建控件的线程访问它的三种方法

访问 Windows 窗体控件本质上不是线程安全的.如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态.还可能出现其他与线程相关的 bug,包括争用情况和死锁.确保以线程安全方式访问控件非常重要. 解决办法 1.把CheckForIllegalCrossThreadCalls设置为false 在多线程程序中,新创建的线程不能访问UI线程创建的窗口控件,如果需要访问窗口中的控件,可以在窗口构造函数中将CheckForIllegalCrossThreadCalls设置为

vc中 动态创建控件

// 动态创建一个静态文本框 CStatic* CPICTUREDlg::CreateOneStatic(LPCTSTR str, CRTSTR Coord, UINT IDC) { CStatic *pStatic =NULL; pStatic = new CStatic; ASSERT_VALID(pStatic); pStatic->Create(str,WS_CHILD|WS_VISIBLE|SS_CENTER,this,IDC); return pStatic; } 动态创建控件,自绘