`
weihe6666
  • 浏览: 432658 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Win32--自定义下拉框

 
阅读更多
Win32--自定义下拉框


上一周要求做一个小的任务,分给我的是自定义下拉框,刚开始接触Windows编程,很多东西都是新的,不知如何去做,如何去查看资料,怎样查资料才会更有效,碰到很多东西,也给我很多启示。

Windows编程中消息贯穿始终,对消息理解不透彻,在编程中往往会迷惑,本文讲解下拉框的相关消息,以及如何自定义下拉框。


一、建立模态对话框
DialogBox (hlnst, MAKEINTRESOURCE(IDD_DIALOG_ICON), hwnd, AboutDlgProc) ;

1.绑定到AboutDlgProc,这个AboutDlgProc回调函数,拦截了对话框的消息,对自己
感兴趣的消息,可以在这里进行处理,不处理的消息返回到系统,由系统处理。这是
一种处理机制,万不可自己处理很多消息,记住只对自己感兴趣的消息进行处理。

2.这句话很重要,就是要把自己不处理的消息,返回给系统,由系统处理:
default:
DefWindowProc (hDlg, message, wParam, lParam) ;
  这里的message是一个消息的代号,即消息的标志,消息在windows中的作用是那么的重要。

3.在对话框建立后会发出初始化消息,在这里进行初始化对话框的组件,即初始化对话框里
的一些控件或者自定义控件,响应这个消息时一定要有返回值,否则系统默认初始化不成功。
case WM_INITDIALOG :
//加载图标
if(!LoadIconBitmaps()) //这里要对加载图标进行判断,但是我后面没有进行判断
{
EndDialog(hDlg,-1);
break;
}
//初始化下拉框
InitComboxList(hDlg);
//设置默认显示
SendDlgItemMessage(hDlg,IDCOMBO,CB_SETCURSEL,0,0);

return TRUE ;

4.WM_MEASUREITEM 消息,所有的自定义控件都要根据这个消息来设置item的大小,
保存在lpMeasureItem = (LPMEASUREITEMSTRUCT) lParam;中,
The WM_MEASUREITEM message is sent to the owner window of a combo box, list box, list view control, or menu item when the control or menu is created.
A window receives this message through its WindowProc function.
这个消息是当下拉框创建时,发送的消息,无论是控件还是资源,都会在创建时发送消息,在这里可以进行相关的初始化设置,这里就是受到这个消息,进行下拉框文本大小的设置。

     case WM_MEASUREITEM:
{
//设置默认下拉框设置
LPMEASUREITEMSTRUCT  lpmis = (LPMEASUREITEMSTRUCT)lParam;
if(lpmis->itemHeight < CY_BITMAP + 2)
lpmis->itemHeight = CY_BITMAP + 2;
break;
}

注意一定要把下拉框设置为自定义:CBS_OWNERDRAWVARIABLE,这个在资源设置面板里设置

4.WM_DRAWITEM 消息,MSDN:
The WM_DRAWITEM message is sent to the parent window of an owner-drawn button,
combo box, list box, or menu when a visual aspect of the button, combo box, list box, or menu has changed.

当Windows要画这个控件时,控件会把此消息发送给父窗口,父窗口接收到这个消息后
对要画的控件进行预设置。

lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
里保存的是要绘制控件的消息

而下拉框控件的消息在对话框初始化发出的消息里就进行了初始化case WM_INITDIALOG

hbmIcon = (HBITMAP) lpdis->itemData;
这句话很重要,这里包含了下拉框很多信息

5.BitBlt函数

BOOL BitBlt(
  HDC hdcDest, // handle to destination DC
  int nXDest,  // x-coord of destination upper-left corner
  int nYDest,  // y-coord of destination upper-left corner
  int nWidth,  // width of destination rectangle
  int nHeight, // height of destination rectangle
  HDC hdcSrc,  // handle to source DC
  int nXSrc,   // x-coordinate of source upper-left corner
  int nYSrc,   // y-coordinate of source upper-left corner
  DWORD dwRop  // raster operation code
);

这个函数是把源目标的像素转移到目标矩形区域,记得还有一个函数可以实现透明的转移

这个函数的目的:画透明的图像,即是把一副图像以一定的透明度混合到目标区域
BLENDFUNCTION blendFunction = { AC_SRC_OVER, 0, 0xff, AC_SRC_ALPHA };
::AlphaBlend(lpdis->hDC, x, lpdis->rcItem.top + 3,
CX_BITMAP, CY_BITMAP, hdc, 0, 0,CX_BITMAP,CY_BITMAP, blendFunction);

源代码:

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     
     switch (message)
     {
     case WM_CREATE :
          hInst = ((LPCREATESTRUCT) lParam)->hInstance ;
          return 0 ;
          
     case WM_COMMAND :
          switch (LOWORD (wParam))
          {
          case ID_HELP_ABOUT :
			   DialogBox(hInst, MAKEINTRESOURCE(IDC_ABOUT_DIALOG), hwnd, AboutDlgProc) ;
               break ;
          }
          return 0 ;
     case WM_PAINT:
		 break;
     case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

INT_PTR CALLBACK AboutDlgProc (HWND hDlg, UINT message, 
                            WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	TCHAR achTemp[256];
     switch (message)
     {
     case WM_INITDIALOG :
		 {//初始化下拉框相关信息
			 if(!LoadIconBitmap())
			 {
				 EndDialog(hDlg,-1);
				 break;
			 }
			 //初始化下拉框
			 InitComboxList(hDlg);
			 SendDlgItemMessage(hDlg,IDCOMBO,CB_SETCURSEL,0,0);
			 return (INT_PTR)TRUE;
		 }
     case WM_MEASUREITEM:
		 {
			 //设置默认下拉框设置
			 LPMEASUREITEMSTRUCT  lpmis = (LPMEASUREITEMSTRUCT)lParam;
			 if(lpmis->itemHeight < CY_BITMAP + 2)
				 lpmis->itemHeight = CY_BITMAP + 2;
			 break;
		 }
	 case WM_DRAWITEM:
		 {
			 //设置下拉框的文本和位图
			 COLORREF clrBackground;
			 COLORREF clrForeground;
			 TEXTMETRIC tm;
			 int x;
			 int y;
			 HRESULT hr;
			 size_t  cch;

			 LPDRAWITEMSTRUCT   lpdis = (LPDRAWITEMSTRUCT)lParam;

			 if(lpdis->itemID == -1)
				 break;

			 //获得item图标
			hbmIcon = (HBITMAP)lpdis->itemData;
			// The colors depend on whether the item is selected.
			clrForeground = SetTextColor(lpdis->hDC, 
				GetSysColor(lpdis->itemState & ODS_SELECTED ?
					COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));

			clrBackground = SetBkColor(lpdis->hDC, 
				GetSysColor(lpdis->itemState & ODS_SELECTED ?
					COLOR_HIGHLIGHT : COLOR_WINDOW));

			// Calculate the vertical and horizontal position.
			GetTextMetrics(lpdis->hDC, &tm);
			y = (lpdis->rcItem.bottom + lpdis->rcItem.top - tm.tmHeight) / 2;
			x = LOWORD(GetDialogBaseUnits()) / 4;

			// Get and display the text for the list item.
			SendMessage(lpdis->hwndItem, CB_GETLBTEXT,
				lpdis->itemID, (LPARAM) achTemp);

			hr = StringCchLength(achTemp, 256, &cch);

			ExtTextOut(lpdis->hDC, CX_BITMAP + 2 * x, y,
				ETO_CLIPPED | ETO_OPAQUE, &lpdis->rcItem,
				achTemp, (UINT)cch, NULL);

			// Restore the previous colors.
			SetTextColor(lpdis->hDC, clrForeground);
			SetBkColor(lpdis->hDC, clrBackground);

			//  Draw the food icon for the item. 
			HDC hdc = CreateCompatibleDC(lpdis->hDC); 
			if (hdc == NULL) 
				break; 

			SelectObject(hdc, hbmMask); 
			BitBlt(lpdis->hDC, x, lpdis->rcItem.top + 1, 
				CX_BITMAP, CY_BITMAP, hdc, 0, 0, SRCAND); 

			SelectObject(hdc, hbmIcon); 
			BitBlt(lpdis->hDC, x, lpdis->rcItem.top + 1, 
				CX_BITMAP, CY_BITMAP, hdc, 0, 0, SRCPAINT); 

			DeleteDC(hdc); 

			// If the item has the focus, draw the focus rectangle.
			if (lpdis->itemState & ODS_FOCUS)
				DrawFocusRect(lpdis->hDC, &lpdis->rcItem);
		  break;
		 }
     case WM_COMMAND :
          switch (LOWORD (wParam))
          {
          case IDOK :
          case IDCANCEL :
               EndDialog (hDlg, -1) ;
               return TRUE ;
			  break;
          }
     }
   return (INT_PTR)FALSE;
}

BOOL LoadIconBitmap()
{
	hbmBread = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BREAD));

	if (hbmBread != NULL)
		hbmMask = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BREAD));

	if (hbmTemp != NULL)
		hbmTemp = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BREAD));

	if (hbmMask != NULL)
		hbmMask = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BREAD));

	if (hbmMask != NULL)
		return TRUE;

}

void InitComboxList(HWND hDlg)
{
	TCHAR achTemp[256] = TEXT("Food");
	TCHAR achTemp_One[256] = TEXT("Dog");
	TCHAR achTemp_Two[256] = TEXT("Fish");
	DWORD dwIndex;

	// Get the handle of the food groups combo box.
	HWND hwndGroupsBox = GetDlgItem(hDlg, IDCOMBO);

	dwIndex = SendMessage(hwndGroupsBox, CB_ADDSTRING, 0, (LPARAM) achTemp);
	SendMessage(hwndGroupsBox, CB_SETITEMDATA, dwIndex, (LPARAM) hbmBread);

	dwIndex = SendMessage(hwndGroupsBox, CB_ADDSTRING, 0, (LPARAM) achTemp_One);
	SendMessage(hwndGroupsBox, CB_SETITEMDATA, dwIndex, (LPARAM) hbmMask);

	dwIndex = SendMessage(hwndGroupsBox, CB_ADDSTRING, 0, (LPARAM) achTemp_Two);
	SendMessage(hwndGroupsBox, CB_SETITEMDATA, dwIndex, (LPARAM) hbmTemp); 

}

分享到:
评论

相关推荐

    让Win7系统右下角的时间栏显示星期几.docx

    在自定义格式窗口中,切换到"日期"选项卡,在日期格式栏作如下修改:短日期(S)下拉框中输入"dddd ddMMM"。 这里需要注意的是,Windows 默认使用的是短日期;当然,你也可以顺手把长日期的格式给改了,在长日期...

    无限级联动下拉菜单 V1.03

    强大的无限级联动下拉菜单类为您建站提供相当的便利条件,...五、可轻松整合各大著名CMS,如帝国等,方便自定义模型的扩展。 备注:内置两个数据JS,一个全国城市省市地区数据,一个人才网站的职位类别职位名称数据。

    TextPro6.5.1正规表达轻易替换

    18. 在“设置-选项-程序”下增加了“集成右键菜单”和“文件关联”的选项(如果在WIN7下,需要以管理员权限运行)。 19. 在“设置-选项-程序”下增加了“粘贴时自动剔除论坛干扰码”选项,此功能较复杂,请慎用。 ...

    FEA 中文前端框架 v1.4.0

    FEA 中文前端框架 v1.4.0 更新信息:修复 subnavJustify 窗口适应添加轮播组件修改关闭按钮默认透明度优化面板优化表单输入框,添加密码输入框,文件输入框,下拉框图标增加及更改[icon-win8 改为 icon-win]添加瀑布...

    工作流程引擎.包含大量文档2012813

    基本功能: 图形化流程设计/智能表单web定义免程序开发/级联下拉框/流程轨迹/单据自定义打印/邮件短信工作到达通知/自动任务分配/支持sdk模式开发/简洁集成/消息侦听/丰富事件接口/报表定义/工作量分析/绩效考核/手机...

    驰骋工作流引擎源码

    基本功能: 图形化流程设计/智能表单web定义免程序开发/级联下拉框/流程轨迹/单据自定义打印/邮件短信工作到达通知/自动任务分配/支持sdk模式开发/简洁集成/消息侦听/丰富事件接口/报表定义/工作量分析/绩效考核/手机...

    QT自定义委托集合(一个类实现11种常用委托,包含源代码和demo)

    1. 一个类实现11种常用委托,使用灵活,可以直接将代码加入到自己的项目中,零耦合。 ... 3. 图标控件:可以指定某一种条件(&lt;、...已经在win和Ubuntu上测试可以正常运行 8. 本demo里面包含我们创建委托类的全部用法。

    TextPro6.5

    18. 在“设置-选项-程序”下增加了“集成右键菜单”和“文件关联”的选项(如果在WIN7下,需要以管理员权限运行)。 19. 在“设置-选项-程序”下增加了“粘贴时自动剔除论坛干扰码”选项,此功能较复杂,请慎用。 ...

    ONGKEYGHOST一键还原

    9、可在下拉框,自定义 Ghost 镜像文件的路径,在安装项可选择默认创建的GHOST目录是否畸形、是否隐藏 10、可搜索畸形目录内的镜像文件及双击可打开相应的目录,在DOS下可搜索全盘的GHO文件并还原 11、程序人性化的...

    具有PageSize更改下拉菜单的GridView自定义分页

    具有自定义分页的GridView控件。

    OnekeyGhost64

    10、可在 Ghost 镜像文件地址栏下拉框,手动输入镜像文件的自定义路径 11、在安装项可设置默认创建的 GHOST目录是否畸形、是否隐藏,可把最后分区设置隐藏或显现 12、可搜索畸形目录内的镜像文件及双击可打开相应的...

    asp.net知识库

    常用编码工具类,支持base64,md5,des,crc32 也谈谈技术面试 在C#里把ArrayList转换为Array 或 把Array转换为ArrayList C# 2.0 在.NET 2.0中,让你的组件也可以绑定 .NET20 一种简单的窗口控件UI状态控制方法 翻译MSDN...

    Qt Creator 的安装和hello world 程序+其他程序的编写--不是一般的好

    一、Qt Creator 的安装和hello world 程序的编写(原创) ...10.在Qt Creator 的menu.qrc 文件中,我们点击Add 下拉框,选择Add Prefix。 我们可以将生成的/new/prefix 前缀改为其他名字,如/File。 ...

    VB6.0动态加载ActiveX控件漫谈

    就可以在代码窗口的左上角的对象下拉框中发现该对象出现了,也就是说,该对象有了 事件或方法了,它的事件有DragDrop,DragOver ,LostFocus ,GotFocus , ObjectEvent和Validate,其中ObjectEvent是通用的事件捕捉...

    winform中的ListBox和ComboBox绑定数据用法实例

    //自定义了Person类(有Name,Age,Heigth等属性) List&lt;Person&gt; persons=new List(); persons.Add(new Person(“WuMiao”,18,175)); persons.Add(new Person(“YeXinYv”,20,170)); persons.Add(new Pe

    qt 获取磁盘空间大小,cpu利用率,内存使用率

    1:封装成一个类,直接调用即可。已经在多个商业项目中使用。 2:所有功能全平台 win linux armlinux 亲测无误,网络上的基本上是烂的或者不可用的,不知道走过多少弯路。...6:自定义颜色下拉框,选择即可看到效果。

    TortoiseSVN

    TortoiseSVN是一个SVN的客户端... 并且你可以对文件添加自定义的属性。 Subversion对待附加属性就像对待文件内容一样, 当修改了一个文件的附加属性(添加,改变,删除附加属性), 即使没有对文件的内容进行修改, ...

    高仿QQ2014,MDI,主题换肤

    8.修复SkinComboBox下拉框项的细节样式。 9.加入SkinFileTansfersContainer控件与SkinFileTransfersItem控件。 SkinFileTansfersContainer:文件传输列表容器,这里面内置Add,Remove,Search等操作ItemList方法。 ...

Global site tag (gtag.js) - Google Analytics