金牌会员
- 积分
- 1765
- 金钱
- 1765
- 注册时间
- 2015-9-21
- 在线时间
- 544 小时
|
- //======================================================================
- // HelloCE - A simple application for Windows CE
- //
- // Written for the book Programming Windows CE
- // Copyright (C) 2003 Douglas Boling
- //======================================================================
- #include <windows.h> // For all that Windows stuff
- #include "helloce.h" // Program-specific stuff
- //----------------------------------------------------------------------
- // Global data 全局变量
- //
- /* TCHAR
- 因为C++支持两种字符串,即常规的ANSI编码(使用""包裹)和Unicode编码(使用L""包裹),这样对应的就有了两套字符串处理函数,比如:strlen和wcslen,分别用于处理两种字符串。
- TCHAR是通过define定义的字符串宏
- 微软将这两套字符集及其操作进行了统一,通过条件编译(通过_UNICODE和UNICODE宏)控制实际使用的字符集,这样就有了_T("")这样的字符串,对应的就有了_tcslen这样的函数
- 为了存储这样的通用字符,就有了TCHAR:
- 当没有定义_UNICODE宏时,TCHAR = char,_tcslen =strlen
- 当定义了_UNICODE宏时,TCHAR = wchar_t , _tcslen = wcslen
- 当我们定义了UNICODE宏,就相当于告诉了编译器:我准备采用UNICODE版本。这个时候,TCHAR就会摇身一变,变成了wchar_t。而未定义UNICODE宏时,TCHAR摇身一变,变成了unsignedchar。这样就可以很好的切换宽窄字符集。
- tchar可用于双字节字符串,使程序可以用于中日韩等国 语言文字处理、显示。使编程方法简化。
- TCHAR 就是当你的字符设置为什么就是什么
- 例如:程序编译为 ANSI, TCHAR 就是相当于 CHAR
- 当程序编译为 UNICODE, TCHAR 就相当于 WCHAR
- TCHAR / _T( ) :
- 如果在程序中既包括ANSI又包括Unicode编码,需要包括头文件tchar.h。TCHAR是定义在该头文件中的宏,它视你是否定义了_UNICODE宏而定义成:
- 定义了_UNICODE: typedef wchar_t TCHAR ;
- 没有定义_UNICODE: typedef char TCHAR ;
- #ifdef UNICODE
- typedef char TCHAR;
- #else
- typede wchar_t TCHAR;
- #endif
- _T( )也是定义在该头文件中的宏,视是否定义了_UNICODE宏而定义成:
- 定义了_UNICODE: #define _T(x) L##x
- 没有定义_UNICODE: #define _T(x) x
- 注意:如果在程序中使用了TCHAR,那么就不应该使用ANSI的strXXX函数或者Unicode的wcsXXX函数了,而必须使用tchar.h中定义的_tcsXXX函数
- 一、 在字符串前加一个L作用:
- 如 L"我的字符串" 表示将ANSI字符串转换成unicode的字符串,就是每个字符占用两个字节。
- strlen("asd") = 3;
- strlen(L"asd") = 6;
- 二、 _T宏可以把一个引号引起来的字符串,根据你的环境设置,使得编译器会根据编译目标环境选择合适的(Unicode还是ANSI)字符处理方式
- 如果你定义了UNICODE,那么_T宏会把字符串前面加一个L。这时 _T("ABCD") 相当于 L"ABCD" ,这是宽字符串。
- 如果没有定义,那么_T宏不会在字符串前面加那个L,_T("ABCD") 就等价于 "ABCD"
- 三、TEXT,_TEXT 和_T 一样的
- 如下面三语句:
- TCHAR szStr1[] = TEXT("str1");
- char szStr2[] = "str2";
- WCHAR szStr3[] = L("str3");
- 那么第一句话在定义了UNICODE时会解释为第三句话,没有定义时就等于第二句话。
- 但二句话无论是否定义了UNICODE都是生成一个ANSI字符串,而第三句话总是生成UNICODE字符串。
- 为了程序的可移植性,建议都用第一种表示方法。
- 但在某些情况下,某个字符必须为ANSI或UNICODE,那就用后两种方法。
- */
- /*HINSTANCE
- 一般用于window窗口程序, 在win32下与HMODULE是相同的东西,在Win32下还存在主要是因为win16。
- HINSTANCE 是“句柄型”数据类型。相当于装入到了内存的资源的ID。HINSTANCE对应的资源是instance.句柄实际上是一个 无符号长整数。但它是“句柄型”,所以你不能把它当成真的无符号长整数,拿来派别的用处,例如,不能拿来做四则运算。HINSTANCE常出现在 API 程序。
- Handle 是代表系统的内核对象,如文件句柄,线程句柄,进程句柄。
- HMODULE 是代表应用程序载入的模块,win32系统下通常是被载入模块的线性地址。
- HINSTANCE 在win32下与HMODULE是相同的东西,在Win32下还存在主要是因为win16
- 程序使用HINSTANCE来区别task。
- HINSTANCE 实际是本模块在内存中的首地址。
- 程序的资源如菜单 对话框 字符 串 光标等等 还有函数 导入导出 表等,都存储在本模块里。
- 所以要使用这些资源必须知道首地址,然后根据预定义的 存储结构 找到各个资源 。
- HINSTANCE是一个指针变量,指向HINSTANCE结构体,而结构体的中只一个int变量。在WINDOWS中句柄多被这种方式进行定义。
- HINSTANCE 是通常用作应用程序实例句柄,可以包含多个窗口实例。
- */
- const TCHAR szAppName[] = TEXT("HelloCE");//应用程序名(使用的是UNICODE/ANSI通用形式)
- HINSTANCE hInst; // 当前实例 程序句柄
- // Message dispatch table for MainWindowProc
- //MainWindowProc的消息调度表
- /*decodeUINT
- struct decodeUINT { //消息和消息函数的关联结构
- UINT Code;
- LRESULT (*Fxn)(HWND, UINT, WPARAM, LPARAM); //这里用到了函数指针
- };
- 这个decodeUINT结构体的使用,使得消息和函数相对应。有了这个消息函数映射表,使得消息能够直接和处理函数很好的关联在一起。
- */
- /*WM_PAINT
- 在计算机中,屏幕上显示的一切东西几乎都是绘制的,包括窗口、对话框、图片、以及一切文字,而WM_PAINT消息就是在绘制这些对象时,系统触发的消息。我们在计算机中的每一个操作,几乎都会触发这个消息,它也是WIndows中最重要的消息之一。
- #define WM_PAINT
- 0x000F
- 程序启动时,绘制窗口时触发。
- 用鼠标调整窗口的大小,时会连续触发。
- 最小化时不会触发WM_PAINT消息,但是从最小化还原时会进行触发。
- 最大化时会触发WM_PAINT消息。
- 当向屏幕外拖动窗口时,不会触发WM_PAINT消息,但是拉回到屏幕内时会不断的触发WM_PAINT消息。
- 使用InvalidateRect函数触发WM_PAINT消息。
- WM_PAINT消息是由系统产生。
- */
- //消息及其处理函数结构体数组
- const struct decodeUINT MainMessages[] = {
- WM_PAINT, //处理窗口的WM_绘制消息。
- DoPaintMain, //处理窗口的WM_绘制消息。
- WM_DESTROY, //处理窗口的WM_销毁消息。
- DoDestroyMain,//处理窗口的WM_销毁消息。
- };
- //======================================================================
- // Program entry point
- //程序入口点是WinMain
- int WINAPI WinMain (
- HINSTANCE hInstance, //程序的句柄
- HINSTANCE hPrevInstance,
- /*LPWSTR
- LPWSTR是wchar_t是一种字符串数据类型
- LPWSTR类型:UNICODE字符串变量,LPWSTR是wchar_t字符串,所以需要按照wchar_t来使用
- 这是错误的用法:
- LPWSTR lpwstr = {0};
- LPWSTR lpwstr = TEXT("你好,世界,这是错误的用法");
- LPWSTR lpwstr = L"你好,世界,这是错误的用法";
- 正确的姿势有三种用法
- 第一种:
- wchar_t lpwstr[32]=L"你好,世界,这是正确的用法";
- 第二种:
- wchar_t lpwstr[32]={0};
- wsprintfw(lpwstr,L"你好,世界,这是正确的用法");
- 第三种:
- MessageBox(hwnd,lpwstr,L"测试",BM_OK);
- LPWSTR和LPCSTR是长指针类型,其本质是一个指针,指向一个长字符串
- LPWSTR一个32位指向unicode字符串,相当于wchar_t
- LPWSTR和LPCSTR是长指针类型,其本质是一个指针,指向一个长字符串
- */
- LPWSTR lpCmdLine, //为了兼容WIN16程序而设置,总为0
- int nCmdShow//指向一个包含命令行文本的UNICODE字符串
- ) {
- MSG msg;//消息
- /*
- MSG是windows程序中的结构体,在WINDOWS程序中,消息是由MSG结构体来表示的,
- */
- int rc = 0;
- HWND hwndMain;//主窗口 窗口句柄
- // Initialize this instance.初始化此实例。
- hwndMain = InitInstance (hInstance, lpCmdLine, nCmdShow);
- //创建主窗口初始化
- if (hwndMain == 0) return 0x10;
- // Application message loop 应用程序消息循环
- while (GetMessage (&msg, NULL, 0, 0)) {
- //GetMessage从调用线程的消息队列里取得一个消息并把其放于指定的结构
- TranslateMessage (&msg);//TranslateMessage该函数将虚拟消息转换成字符消息,字符消息被寄送到调用线程的消息队列里
- DispatchMessage (&msg);//DispatchMessage该函数功能是凋度一个消息给窗口程序
- }
- // Instance cleanup 实例清理
- return TermInstance (hInstance, msg.wParam);
- }
- //----------------------------------------------------------------------
- // InitInstance - Instance initialization
- // 实例初始化
- HWND InitInstance (HINSTANCE hInstance, LPWSTR lpCmdLine, int nCmdShow) {
- WNDCLASS wc;
- HWND hWnd;
- // Save program instance handle in global variable.
- //将程序实例句柄保存在全局变量中。
- hInst = hInstance;
- #if defined(WIN32_PLATFORM_PSPC)
- // If Pocket PC, only allow one instance of the application
- //如果是Pocket PC,则只允许应用程序的一个实例
- HWND hWnd = FindWindow (szAppName, NULL);
- if (hWnd) {
- SetForegroundWindow ((HWND)(((DWORD)hWnd) | 0x01));
- return -1;
- }
- #endif
- // Register application main window class.
- //注册应用程序主窗口类。
- wc.style = 0; // Window style 样式
- wc.lpfnWndProc = MainWndProc; // Callback function 回调函数 指定窗口过程函数
- wc.cbClsExtra = 0; // Extra class data 额外类数据
- wc.cbWndExtra = 0; // Extra window data 额外窗口数据
- wc.hInstance = hInstance; // Owner handle 所有者句柄
- wc.hIcon = NULL, // Application icon 应用程序图标
- wc.hCursor = LoadCursor (NULL, IDC_ARROW);// Default cursor 默认光标
- wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);//窗口背景颜色
- wc.lpszMenuName = NULL; // Menu name 菜单名
- wc.lpszClassName = szAppName; // Window class name 窗口类名称
- //注册窗口类
- if (RegisterClass (&wc) == 0) return 0;
- // Create main window. 创建主窗口。
- hWnd = CreateWindow (szAppName, // Window class 窗口类
- TEXT("HelloCE for FL2440"), // Window title 窗口标题
- // Style flags
- WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
- /*
- 自定义位置
- 0, // x position x位置
- 0, // y position y位置
- 200, // Initial width 初始宽度
- 100,//CW_USEDEFAULT, // Initial height 初始高度
- */
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- NULL, // Parent 父窗口
- NULL, // Menu, must be null 菜单,必须为空 WINCE窗口不支持菜单
- hInstance, // Application instance 应用实例
- NULL); // Pointer to create 指向创建的指针
- // parameters 参数
- if (!IsWindow (hWnd)) return 0; // Fail code if not created. 如果未创建失败代码。
- // Standard show and update calls 标准显示和更新呼叫
- ShowWindow (hWnd, nCmdShow);//使窗口的属性和主程序指定的相同
- UpdateWindow (hWnd);//强制WIN发送WIM_PAINT消息给刚创建的窗口
- return hWnd;
- }
- //----------------------------------------------------------------------
- // TermInstance - Program cleanup 程序清理
- //
- int TermInstance (HINSTANCE hInstance, int nDefRC) {
- return nDefRC;
- }
- //======================================================================
- // Message handling procedures for main window
- // 主窗口的消息处理过程
- //----------------------------------------------------------------------
- // MainWndProc - Callback function for application window
- // 应用程序窗口的回调函数
- LRESULT CALLBACK MainWndProc (HWND hWnd, UINT wMsg, WPARAM wParam,
- LPARAM lParam) {
- INT i;
- //
- // Search message list to see if we need to handle this
- // message. If in list, call procedure.
- // 搜索邮件列表以查看是否需要处理此邮件。如果在列表中,则调用过程。
- for (i = 0; i < dim(MainMessages); i++) {
- if (wMsg == MainMessages[i].Code)
- return (*MainMessages[i].Fxn)(hWnd, wMsg, wParam, lParam);
- }
- return DefWindowProc (hWnd, wMsg, wParam, lParam);//没有编写对应的函数则调用默认的
- }
- //----------------------------------------------------------------------
- // DoPaintMain - Process WM_PAINT message for window. 处理窗口的WM_绘制消息。
- //
- LRESULT DoPaintMain (HWND hWnd, UINT wMsg, WPARAM wParam,
- LPARAM lParam) {
- PAINTSTRUCT ps;
- RECT rect;
- HDC hdc;
- // Get the size of the client rectangle 获取客户端矩形的大小
- GetClientRect (hWnd, &rect);
- //自定义矩形大小
- //rect.top=0;
- //rect.left=0;
- //rect.right=200;
- //rect.bottom=100;
- hdc = BeginPaint (hWnd, &ps);
- /*
- 文本输出函数
- int DrawText(//通过DrawText可以将一段文字输出到指定的区域去
- HDC hDC,//表示设备环境
- LPCTSTR lpString,//被输出的字符串的指针
- int nCount,//字符串中的字符数
- LPRECT lpRect,//文本的显示矩形区域
- UINT uFormat//文本的显示方法
- );
- 设置文本的背景颜色-COLORREF SeTBkColor( HDC hdc,COLORREF crColor);
- 设置文本颜色-COLORREF SetTextColor(HDC hdc,COLORREF crColor);
- 文本的对齐方式-UINT SetTextAlign(HDC hdc,UINT fmode);
- 此功能在指定矩形中绘制格式化文本。绘取文本根据指定格式方法对文本进行格式化。
- int DrawText(
- HDC hDC, //处理设备上下文。
- LPCTSTR lpString, //长指指向您想要绘制的字符串。如果nCount参数为 1,则必须指定空终止字符串。
- int nCount, //整数中,该整数指定字符串中的字符数。如果nCount是 [1,DrawText 假定lpString参数是空端字符串的指点,并自动计算字符计数。
- LPRECT lpRect, //长指头到包含矩形的RECT结构,在逻辑坐标中,您希望在其中对文本进行格式化。
- UNIT uFormat//未签名的整数, 指定格式化文本的方法。下表显示了您可以组合以创建此参数值的可能值。
- );
- DT_BOTTOM将文本证明为矩形底部。您必须将此值与DT_SINGLELINE相结合。
- DT_CALCRECT确定矩形的宽度和高度。如果矩形包含多个文本行,DrawText使用lpRect参数指向的矩形的宽度,并扩展矩形的底部以绑定文本的最后一行。如果矩形仅包含一行文本,DrawText会修改矩形的右侧,以便将行中的最后一个字符绑定。无论哪种情况,DrawText 都返回格式文本的高度,但不绘制文本。在调用DrawText之前,应用程序必须设置由lpRect指向的RECT结构的右侧和底部成员。这些成员更新了与抽签文本的呼叫。
- DT_CENTER中心在矩形中水平文本。
- DT_END_ELLIPSIS截断比显示矩形更宽的文本字符串,并添加椭圆以表示截断。
- DT_EXPANDTABS扩展选项卡字符。每个选项卡的默认字符数为 8。
- DT_INTERNAL使用系统字体计算文本指标。
- DT_LEFT将文本对齐到左侧。
- DT_NOCLIP无需剪报即可绘制。使用DT_NOCLIP时,绘取文本会更快一些。
- DT_NOPREFIX关闭前缀字符的处理。通常,DrawText将造音前缀字符 (作为强调以下字符的指令, 以及 mnemonic 前缀字符 ) 解释为打印单个字符的指令。通过指定DT_NOPREFIX,此处理被关闭。
- DT_RIGHT将文本对齐到右侧。
- DT_RTLREADING当选择进入 hdc 的字体为希伯来语或阿拉伯语字体时,按从右到左的阅读顺序进行双向文本的布局。所有文本的默认读取顺序为从左到右。
- DT_SINGLELINE仅在单行上显示文本。运输返回和线路源不会断线。
- DT_TABSTOP设置选项卡停止。位 8-15,它构成了低阶字的高阶字体,uFormat参数指定每个选项卡的字符数。每个选项卡的默认字符数为 8。您不能使用具有DT_TABSTOP值的DT_CALCRECT、DT_EXTERNALLEADING、DT_INTERNAL、DT_NOCLIP和DT_NOPREFIX值。
- DT_TOP最有根据的文本。您必须将此值与DT_SINGLELINE相结合。
- DT_VCENTER中心垂直文本。您必须将此值与DT_SINGLELINE相结合。
- DT_WORD_ELLIPSIS截断任何不适合显示矩形的单词,并添加椭圆形。
- DT_WORDBREAK打断文字。如果一个单词会延伸至lpRect参数指定的矩形边缘,则 DrawText会自动打破单词之间的界线。运输回线源序列也打破了这条线。
- 回报值 文本的高度表示成功。零表示故障。
- 绘取文本功能使用选定的字体、文本颜色和背景颜色为设备上下文绘制文本。除非指定DT_NOCLIP值,否则 DrawText会剪辑文本,使其不会出现在指定矩形之外。DrawText假定所有格式都有多个行,除非您指定DT_SINGLELINE格式。
- 如果选定的字体对于指定矩形来说太大,则 DrawText功能不会尝试替换较小的字体。
- 对于 Windows CE 2.10 及以后,支持中文、韩文和日文的断线。
- */
- SetTextColor(hdc,RGB(0,0,0xff));//设置字体颜色
- DrawText (hdc, TEXT ("Hello Windows CE!"), -1, &rect,
- DT_CENTER | DT_VCENTER | DT_SINGLELINE);
- EndPaint (hWnd, &ps);
- return 0;
- }
- //----------------------------------------------------------------------
- // DoDestroyMain - Process WM_DESTROY message for window.
- // 处理窗口的WM_销毁消息。
- LRESULT DoDestroyMain (HWND hWnd, UINT wMsg, WPARAM wParam,
- LPARAM lParam) {
- PostQuitMessage (0);
- return 0;
- }
复制代码
|
|