《DuiLib学习》-- 基本知识及基本语法

1.#pragma comment 的使用方法

#pragma comment ( lib,"wpcap.lib" )

表示链接wpcap.lib这个库。
和在工程设置里写上链入wpcap.lib的效果一样(两种方式等价,或说一个隐式一个显式调用),不过这种方法写的 程序别人在使用你的代码的时候就不用再设置工程settings了。告诉连接器连接的时候要找ws2_32.lib,这样你就不用在linker的lib设置里指定这个lib了。

比如:

#include "Mwic_32.h"  
#pragma comment(lib,"Mwic_32.lib")  

就不需要在project setting里面设置了
 

注释 pragma 可以允许用户在目标文件或可执行文件中插入注释。lib 指定符允许用户向链接器传递该注释,以在使用对象模块时指定其它的链接库。有些用户使用 lib 注释 pragma 以添加链接器选项和库名,例如:

#pragma comment(lib, "MSVCRT -VERBOSE")

在 Visual C++ 2.x 中,代码行照原样将字符串传递给链接器,结果导致编译时附加了 /VERBOSE 链接器选项和 MSVCRT.LIB 库。但是,这种情况并不仅限于上述方式。编译器不会将注释字符串放在引号内,而会用空格分隔文本。

在 Visual C++ 4.0、4.1、和 4.2 中,编译器将注释字符串正确地放在引号内,因而导致上述代码产生以下错误:

LINK :fatal error LNK1104:cannot open file "MSVCRT -VERBOSE.lib"

// Compile options needed:none  
// test.c  
#pragma comment(lib,"MYLIBRARY -VERBOSE")  
void main(void)  
{  
}  
#pragma comment( comment-type [,"commentstring"] )  

参考链接:https://blog.csdn.net/haiross/article/details/44940455

2.基本类

一、核心类
1.        CWindowWnd,窗口对象管理父类,主要作用:

1)        创建窗口。

2)        窗口消息过程处理。

3)        提供窗口子类化与超类化接口。

2.        CDialogBuilder,控件布局类,主要作用:

1)        读取XML脚本,分析脚本,构建控件树。

2)        创建控件对象。

3.        CPaintManagerUI,窗口消息及图形绘制管理器类,与窗口绑定,主要作用:

1)        绘制控件。

2)        消息管理。

3)        事件通知。

4.        INotifyUI,事件通知抽象类,主要作用:

1)        重载Notify虚函数,处理事件通知。

二、控件类
1.        CControlUI,控件管理父类,主要作用:

1)        控件的通用基类,提供控件通用属性管理。

2.        CLabelUI,静态标签类,父类CControlUI。

3.        CButtonUI,按钮类,父类CLabelUI。

4.        COptionUI,选择按钮类,父类CButtonUI。

5.        CTextUI,静态文本类,父类CLabelUI。

6.        CProgressUI,进度条类,父类CLabelUI。

7.        CSliderUI,父类CProgressUI。

8.        CEditUI,编辑框类,父类CLabelUI。

9.        CListUI,列表框类,父类CVerticalLayoutUI、IListUI。

1)        CListHeaderUI,父类CHorizontalLayoutUI。

2)        CListHeaderItemUI,列表头类,父类CControlUI。

3)        CListTextElementUI,类表文本类,父类CListLabelElementUI。

4)        CListLabelElementUI,父类CListElementUI。

10.    CComboUI,组合框类,父类CContainerUI、IListOwnerUI。

11.    CActiveXUI,ActiveX控件类,父类CControlUI、 IMessageFilterUI。

12.    CContainerUI,容器类,父类CControlUI、IContainerUI。

13.    CTabLayoutUI,选项页布局类,父类CContainerUI。

14.    CTileLayoutUI,父类CContainerUI。

15.    CDialogLayoutUI,对话框布局类,父类CContainerUI。、

16.    CVerticalLayoutUI,垂直布局类,父类CContainerUI。

17.    CHorizontalLayoutUI,水平布局类,父类CContainerUI。

18.    CListExpandElementUI,父类CListTextElementUI。

19.    CListContainerElementUI,父类CContainerUI、IListItemUI。

三、辅助类
       1.        CStdPtrArray,指针数组。

2.        CStdValArray,数据数组。

3.        CStdString,字符串数组。

4.        CStdStringPtrMap,字符串指针映射数组。

参考链接:https://www.cnblogs.com/xubin0523/archive/2012/06/01/2530901.html

3.CDuiString类

它是Duilib库中对字符串对象的一个封装,里面包含了对字符串的常用操作。

4.GetSkinFolder ()与 SetResourcePath() 

(1)关于资源设置的函数说明:

这三个函数的说明如下:

1、 GetSkinFolder () 需要返回 皮肤XML 所在的文件夹

2、GetSkinFile () 需要返回 皮肤 XML 的文件名(也可以包含路径)

3、GetWindowClassName () 需要返回这个窗口的类名,这个类名用于 RegisterClass.

这三个函数告知duilib库应该从哪个文件夹下解析哪个xml文件,并定义对应窗口的名字,以后这个类就代表这个xml文件所描述的窗口

需要注意的是这些函数必须在头文件中这样写,我自己写在CPP文件中它在运行时报错,可能是库本身的bug

(2)注意事项:

实际如果 SetResourcePath 设定了目录, GetSkinFolder 无效,只能通过 GetSkinFile 来实现,可以以这种方式返回 _T("about/about.xml");,实际上就是 GetSkinFile 做了 GetSkinFolder + GetSkinFile 的工作

WindowImplBase已经将CPaintManagerUI::SetResourcePath(CPaintManagerUI::GetInstancePath())封装到内部了,GetSkinFolder 在此路径基础上设定资源文件夹路径

CPaintManagerUI::GetInstancePath()的路径是生成exe的路径

参考链接:duilib基本流程

5.C++ - _T含义 C++语言中“_T”是什么意思?

_T("")是一个宏,定义于tchar.h下。

#define __T(x) L ## x

#define _T(x) __T(x)

--------------------------------------------------------------

_T("Hello")是一个宏,他的作用是让你的程序支持Unicode编码,因为Windows使用两种字符集ANSIUNICODE,前者就是通常使用的单字节方式,但这种方式处理象中文这样的双字节字符不方便,容易出现半个汉字的情况。而后者是双字节方式,方便处理双字节字符。

Windows NT的所有与字符有关的函数都提供两种方式的版本,而Windows 9x只支持ANSI方式。 

如果你编译一个程序为ANSI方式,_T实际不起任何作用。而如果编译一个程序为UNICODE方式,则编译器会把"Hello"字符串以UNICODE方式保存。

_T_L的区别在于,_L不管你是以什么方式编译,一律以UNICODE方式保存。

---------------------------------------------------------------------------------------------------------------

1\C++语言中“_T”是什么意思? 

Visual C++里边定义字符串的时候,用_T来保证兼容性,VC支持asciiunicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。

如果将来你不打算升级到unicode,那么也不需要_T, 

--------------------------------------------------------- 

_t("hello world") 

ansi的环境下,它是ansi的,如果在unicode下,那么它将自动解释为双字节字符串,既unicode编码。 

这样做的好处,不管是ansi环境,还是unicode环境,都适用。 

2\请问在vc++中的字符串_T("ABC")和一个普通的字符串“ABC”有什么区别。 

_T("ABC") 

表示如果定义了unicode 

它表示 L"ABC",每个字符为16位,宽字符字符串 

--------------------------------------------------------- 

if not UNICODE 

它就是ascii"ABC",每个字符为8位 

"ABC"就是指ascii字符串"ABC" 

---------------------------------------------------------- 

相当于 

#ifdef _UNICODE 

#define _T("ABC") L"ABC" 

#else 

#define _T("ABC") "ABC" 

#endif 

---------------------------------------------------------- 

_T("ABC")中的一个字符和汉字一样,占两个字节,而在"ABC"中,英文字符占一个字节,汉字占两个字节

---------------------------------------------------------------------------------------------------------------

_Ttchar.h头文件中定义了:

#define __T(x)      L ## x

#define _T(x)       __T(x)

-- ##在宏里面相当于连接符,把前后两个字符串连在一起作为一个字符串。

以下来自网络:

#define Conn(x,y) x##y

#define ToChar(x) #@x

#define ToString(x) #x

x##y表示什么?表示x连接y,举例说:

int n = Conn(123,456); 结果就是n=123456;

char* str = Conn("asdf", "adf")结果就是 str = "asdfadf";

怎么样,很神奇吧

再来看#@x,其实就是给x加上单引号,结果返回是一个const char。举例说:

char a = ToChar(1);结果就是a='1';

做个越界试验char a = ToChar(123);结果是a='3';

但是如果你的参数超过四个字符,编译器就给给你报错了!error C2015: too many characters in constant   :P

最后看看#x,估计你也明白了,他是给x加双引号

char* str = ToString(123132);就成了str="123132";

参考链接:https://blog.csdn.net/CNHK1225/article/details/45097281

7.关于Notify:

(1)消息泵的处理流程

WindowImplBase的OnCreate函数默认会将自身添加成CPaintManagerUI Notify消息的Notifier,WindowImplBase对象相当于是事件消息的一个监听者,当有事件发生时,会调用WindowImplBase的Notify函数,而Notify函数会调用CNotifyPump::NotifyPump进入消息泵。进入消息泵后,先查看当前窗口类中有无虚拟窗口对事件进行处理,如果没有,就查找当前窗口类是否有函数对其进行处理,如果没有,进入父类进行类似查找,直到CNotifyPump类。

(2)控件响应处理:

父类 WindowImplBase 提供了 Notify 虚函数,可以提供我们覆写并处理消息。最后别忘记调用父类的 Notify 函数来继续其他消息的处理(其实父类什么都没做,)。

void MyMainWindow::Notify(TNotifyUI& msg)
{
	if (msg.sType == _T("click")) 
	{
		CDuiString sName = msg.pSender->GetName();
		if (sName == _T("closebtn"))
		{
			Close(IDOK);
			PostQuitMessage(0);
			return;
		}
	}
	WindowImplBase::Notify(msg);
}

参考链接:控件消息响应处理

(3)消息队列机制:(扩展)

参考链接:https://blog.csdn.net/xiaojun111111/article/details/49565719

8.duilib关闭窗口方式:

Close(IDOK) , Close(IDCANCEL);

9.void PostQuitMessage(0)函数:

//void PostQuitMessage(int nExitCode)函数的作用是向程序发送WM_QUIT消息,nExitCode应用程序退出代码

PostQuitMessage(0); //调用该函数发出WM_QUIT消息

(1)WM消息传递过程原理:

从用户单击关闭按钮(标题栏最右边)或者用鼠标或鍵盘选择系统菜单的“关闭”选项,直到窗口消失,应用程序结束。这期间到底发生了什么呢?这曾经是我百思不得其解的问题,我想也会有很多人和我一样会碰到这个问题。所以我要把我的一些学习心得写出来,与大家共享:  

  1、首先会产生一个WM_SYSCOMMAND消息,如果程序员没有对此消息进行拦截,则由缺省的窗口函数DefWindowProc进行处理,如果表达式(LOWORD(wParam)&0xFFF0)==SC_CLOSE   成立,DefWindowProc发出一个WM_CLOSE消息。  

  2、同样,如果程序员没有对WM_CLOSE消息进行拦截,则还是由DefWindowProc进行处理,这次,她只简单的调用 DestroyWindow函数,DestroyWindow先把窗口破坏掉,使用户看不到窗口。但是窗口破坏后,应用程序并没有结束,于是 DestroyWindow再接再励,送出了一个WM_DESTROY消息。  

  3、这一次,WM_DESTROY被载获了,通常是会有这样的句子:  

  case   WM_DESTROY:  

  PostQuitMessage(0);  

  ...  

  这里PostQuitMessage函数很简单的发送一个WM_QUIT消息来响应WM_DESTROY  

  4、WM_QUIT消息非常特殊,她使GetMessage函数返回0,从而结束了消息循环,  

  应用程序从此结束。  

(2)扩展:WM_CLOSE WM_QUIT WM_DESTROY 三者的区别

一直以来,我都不是很明白这三个的区别,今天看了一写文章,才明白过来,一下是转载的文字:

有三个消息看 起来差不多,都是处理关闭的事情的。它们是WM_DESTROY,WM_CLOSE,和WM_QUIT。它们的确很相似,但你需要知道它们之间的不同!一 个窗口或者应用程序应该被关闭时发出WM_CLOSE消息,当接收到WM_CLOSE消息时,如果你愿意,向用户提出是否真的退出。你知道让用户作确认或 有错误出现或有什么应该注意的事情发生的时候,往往弹出一个消息框。

插播消息框

 int MessageBox(

 HWND hWnd, // handle of owner window

 LPCTSTR lpText, // address of text in message box

 LPCTSTR lpCaption, // address of title of message box

 UINT uType // style of message box

 );

 当收到WM_CLOSE消息,你可以做两件事儿。一件是你接受默认的处理返回一个值,你若这样做了,应用程序或窗口按照计划关闭;再者,你返回0,应用程序或窗口将保持原样。以下是代码的基本部分:

 if (msg == WM_CLOSE)

 {

 if (MessageBox(hMainWindow, "Are you sure want to quit?", "Notice", MB_YESNO | MB_ICONEXCLAMATION) == IDNO)

 return(0);

 // otherwise, let the default handler take care of it

 }

 WM_DESTROY消息有点儿不同。它是窗口正在关闭时发出的。

 当得到WM_DESTROY消息的时候,窗口已经从视觉上被删除。

 一个主窗口被关闭,并不意味着应用程序结束了,它将在没有窗口的条件下继续运行。

 然而,当一个用户关闭了主窗口,也就意味着他要结束应用程序,所以如果你希望应用程序结束,在收到WM_DESTROY消息的时候,你必须发出一个WM_QUIT消息。

 WM_QUIT是应用程序结束发出的消息,一般可以看成进程被kill掉的情况.

PostQuitMessage是向系统发出要终止线程的请求, 在终止线程前系统还要做些内存的清理工作, 我们关闭一个程序时是发送WM_CLOSE消息, 然后调用DestroyWindow函数,调用DestroyWindow时系统会向程序发WM_DESTROY消息,终止整个程序

用自己的话总结一下:WM_CLOSE 消息发出的时候,用户可以根据自己的意愿来选择到底是否关闭,WM_DESTORY 是真的关闭一个窗口。WM_QUIT是退出一个应用程序

参考链接:https://blog.csdn.net/tunnel115/article/details/4546913

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值