zoukankan      html  css  js  c++  java
  • <Win32_14>__win32控件(2)__教你自学掌握所有控件的玩法

    学习win32 API 编程,我们应该善于利用微软给我们提供的一些辅助工具,例如大家都知道的MSDN、SPY++等等。

    今天在讲述之前呢,先给大家介绍一个很有用的工具——Control Spy——它的用途和SPY++有点儿类似,它能查看对应控件所属的风格、能响应的消息以及响应的通知码。

    有了它,加上msdn,你基本上就能很快掌握这些控件的用法了——都是基于消息驱动来完成响应的工作

    (点击下载Control Spy小工具)

    OK,先来讲一下这个小工具的用法(包含个人的学习心得):

    (1)在左边子窗口中,选择你想学习的控件,这里我就选择Button

    (2)在中间子窗口中你就能预览这个控件的样式

    (3)我们知道,这些控件其实本质上都是窗口,因此他们都可以用CreateWindow或者CreateWindowEx函数来创建

    下面,我详细讲一下创建的过程(为了帮助说明,我将以CreateWindow函数为例,并贴出该函数的原型声明)

    HWND CreateWindow(
      LPCTSTR lpClassName,  // registered class name
      LPCTSTR lpWindowName, // window name
      DWORD dwStyle,        // window style
      int x,                // horizontal position of window
      int y,                // vertical position of window
      int nWidth,           // window width
      int nHeight,          // window height
      HWND hWndParent,      // handle to parent or owner window
      HMENU hMenu,          // menu handle or child identifier
      HINSTANCE hInstance,  // handle to application instance
      LPVOID lpParam        // window-creation data
    );
    

    我只列出需要注意的几个特别参数的设法

    1>窗口类的名称lpClassName——微软帮预设了对应控件所关联的窗口类名称——因此,你只需要将它设为TEXT("控件的英文名称")

        例如,我这里选择按钮Button,你就可以写为TEXT("button");如果选择组合框ComboBox,就写为TEXT("combobox")

        注:名称不区分大小写,因此你在创建主窗口的时候,就不能将主窗口的窗口类名称设为这些控件的名称,免得覆盖了微软预设的控件窗口类名称

    2>窗口的风格dwStyle——这时刚刚提到的小工具就起作用了,你可以在它的子窗口Style中,查找对应的类型:

    不过类型WS_CHILD是必须添加的,如果你想让改控件一创建就可见,那么就应该还加上WS_VISIBLE

    3>父窗口hWndParent,由于这些控件都是子窗口,所以父窗口一定不能为空,这个之情况而定

    4>菜单句柄hMenu,这个需要设定为控件的ID号(ID一般就是用宏定义的一些常量,例如:IDB_BUTTON  按钮ID号)

    为了类型的匹配,你需要强制转换一下类型:(HMENU)IDB_BUTTON

    5>实例句柄hInstance,如果你是在主窗口的WM_CREATE消息中创建控件,那么可以这样设定:((LPCREATESTRUCT)lParam)->hInstance

    (4)了解控件能响应的消息:

    (5)你还可以操作,这个控件来看看它所响应的消息以及对应的通知码

    消息:

    通知码:

    好了,这个小工具的大致使用方法就介绍到这里,如果你还是不怎么清楚它的用法,可以参见资源下载中提供的英文版帮助文档 

    光说不练是假把式,还是用程序代码来证明一切

    昨天讲了按钮的创建以及使用方法,今天儿就讲一下组合框的使用方法。

    还是先来看看实现的效果:

    可以看见,我还是使用WinXP以来微软提供的新控件,毕竟要美观些

    ***************************************************进入代码阶段******************************************************

    先在头文件做一些相应的声明

    //WINDOW_XP_STYLE.H
    
    #include<windows.h>
    
    //组合框的ID
    #define IDCB_COMBOBOX_1	100
    #define IDCB_COMBOBOX_2	101
    #define IDCB_COMBOBOX_3	103
    //组合框的个数
    #define NUMS			3
    
    //一些字符串数组,用于显示
    TCHAR* tchSmall[]	= {TEXT("小美女"), TEXT("小帅哥"), TEXT("小可爱")};
    TCHAR* tchBig[]		= {TEXT("大美女"), TEXT("大帅哥"), TEXT("小顽皮")};
    TCHAR* tchNone[]	= {TEXT("漂亮"), TEXT("帅气"), TEXT("可爱")};
    
    //使用WinXP以来提供的心控件
    #pragma comment(linker,""/manifestdependency:type='win32' "
    						"name='Microsoft.Windows.Common-Controls' "
    						"version='6.0.0.0' processorArchitecture='*' "
    						"publicKeyToken='6595b64144ccf1df' language='*'"")
    
    


     

    因为大部分技术都是在前面博文中讲述过的,这里我就仅仅将完整代码贴出来,内含一定的注释,只要各位有一定的基础,应该是能看懂的^_^

    //ComboBox.c
    #include<windows.h>
    #include"Window_Xp_Style.h"
    
    LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
    
    int WINAPI WinMain(HINSTANCE hInstance,
    				   HINSTANCE hPrevInstance,
                       PSTR szCmdLine,
    				   int iCmdShow)
    {
    	static	TCHAR	szAppName[] = TEXT("ComboBox View");//注意这里不能写为ComboBox  因为这样会覆盖微软预设的控件窗口类名称
    	HWND			hwnd;
    	MSG				msg;
    	WNDCLASS		wndclass;
    	int				cxScreen, cyScreen;
    	
    	wndclass.style			= CS_HREDRAW | CS_VREDRAW;
    	wndclass.lpfnWndProc	= WndProc;
    	wndclass.cbClsExtra		= 0;
    	wndclass.cbWndExtra		= 0;
    	wndclass.hInstance		= hInstance;
    	wndclass.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
    	wndclass.hCursor		= LoadCursor(NULL, IDC_ARROW);
    	wndclass.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
    	wndclass.lpszMenuName	= NULL;
    	wndclass.lpszClassName	= szAppName;
    	
    	if(!RegisterClass(&wndclass))
    	{
    		MessageBox(NULL, TEXT("This program requires Windows NT!"),
    			szAppName, MB_ICONERROR);
    		return 0;
    	}
    	
    	cxScreen = GetSystemMetrics(SM_CXSCREEN);
    	cyScreen = GetSystemMetrics(SM_CYSCREEN);
    	hwnd = CreateWindow(szAppName,
    						TEXT("ComboBox Demo"),
    						WS_OVERLAPPEDWINDOW,
    						cxScreen  * 7 / 20,
    						cyScreen / 4,
    						cxScreen * 3 / 10,
    						cyScreen / 2,
    						NULL,
    						NULL,
    						hInstance,
    						NULL);
    
    	ShowWindow(hwnd, iCmdShow);
    	UpdateWindow(hwnd);
    
    	while(GetMessage(&msg, NULL, 0, 0))
    	{
    		TranslateMessage(&msg);
    		DispatchMessage(&msg);
    	}
    	
    	return msg.wParam;
    }
    
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    	static HWND	hComboBox[NUMS];//组合框窗口句柄数组(有3个)
    	int			iCombID[] = {IDCB_COMBOBOX_1, IDCB_COMBOBOX_2, IDCB_COMBOBOX_3};//组合框ID数组
    	HFONT		hFont;//字体句柄
    	LOGFONT		lf;
    	int			i, xPos, yDiv;//循环变量、组合框x坐标、y坐标上的间距
    
    	switch(message)
    	{
    	case WM_CREATE:
    		//创建组合框
    		for(i=0; i<NUMS; i++)
    		{
    			hComboBox[i] = CreateWindow(TEXT("combobox"), TEXT(""),
    							WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_HASSTRINGS | CBS_SIMPLE,
    							0, 0, 0, 0, hwnd, (HMENU)iCombID[i],
    							((LPCREATESTRUCT)lParam)->hInstance, NULL);
    		}
    
    		//添加子项
    		for(i=0; i<NUMS; i++)
    			SendMessage(hComboBox[0], CB_ADDSTRING, 0, (LPARAM)tchSmall[i]);
    
    		for(i=0; i<NUMS; i++)
    			SendMessage(hComboBox[1], CB_ADDSTRING, 0, (LPARAM)tchBig[i]);
    
    		for(i=0; i<NUMS; i++)
    			SendMessage(hComboBox[2], CB_ADDSTRING, 0, (LPARAM)tchNone[i]);
    
    		//设置初始状态选中的子项
    		for(i=0; i<NUMS; i++)
    			SendMessage(hComboBox[i], CB_SETCURSEL, (WPARAM)0, 0);
    
    		//创建字体
    		ZeroMemory(&lf, sizeof(LOGFONT));
    		lf.lfHeight	= -10;
    		hFont = CreateFontIndirect(&lf);
    
    		//修改当前的字体
    		for(i=0; i<NUMS; i++)
    			SendMessage(hComboBox[i], WM_SETFONT, (WPARAM)hFont, 0);
    
    	  	return 0;
    
    	case WM_SIZE:
    		//随着窗口大小的改变而移动组合框
    		xPos = (LOWORD(lParam) - 100) / 2;
    		yDiv = HIWORD(lParam) / (NUMS + 2);
    
    		for(i=0; i<NUMS; i++)
    			MoveWindow(hComboBox[i], xPos, yDiv * (i + 1), 100, 20, TRUE);
    		return 0;
    
    	//响应组合框子项选择的消息
    	case WM_COMMAND:
    		//判断控件的ID
    		switch(LOWORD(wParam))
    		{
    		case IDCB_COMBOBOX_1:
    			//判断当前控件对应的通知码
    			if(HIWORD(wParam) == CBN_SELENDOK)//选择了组合框的子项
    			{
    				LRESULT index;
    				index = SendMessage(hComboBox[0], CB_GETCURSEL, 0, 0);
    
    				if(CB_ERR != index)
    					MessageBox(hwnd, tchSmall[(int)index], TEXT("提示"), MB_OK);
    			}
    			break;
    
    		case IDCB_COMBOBOX_2:
    			//判断当前控件对应的通知码
    			if(HIWORD(wParam) == CBN_SELENDOK)
    			{
    				LRESULT index;
    				index = SendMessage(hComboBox[1], CB_GETCURSEL, 0, 0);
    
    				if(CB_ERR != index)
    					MessageBox(hwnd, tchBig[(int)index], TEXT("提示"), MB_OK);
    			}
    			break;
    
    		case IDCB_COMBOBOX_3:
    			//判断当前控件对应的通知码
    			if(HIWORD(wParam) == CBN_SELENDOK)
    			{
    				LRESULT index;
    				index = SendMessage(hComboBox[2], CB_GETCURSEL, 0, 0);
    
    				if(CB_ERR != index)
    					MessageBox(hwnd, tchNone[(int)index], TEXT("提示"), MB_OK);
    			}
    			break;
    		}
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    
    	return DefWindowProc(hwnd, message, wParam, lParam);
    }
    
  • 相关阅读:
    saltstack笔记
    saltstack学习篇
    tomcat学习篇
    memcache笔记
    sed、awk学习篇
    javascript function call
    jvm性能调优工具
    spring boot 单元测试
    activemq 分布式事务
    sringboot 集成dobbo2.5.3
  • 原文地址:https://www.cnblogs.com/riskyer/p/3279863.html
Copyright © 2011-2022 走看看