`
weihe6666
  • 浏览: 440382 次
  • 性别: 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); 

}

分享到:
评论

相关推荐

    Win32DiskImager-0.9.5-binary

    **Win32DiskImager-0.9.5-binary** 是一个专为Windows 7和Windows 8用户设计的实用工具,主要用于在树莓派2上安装和烧写镜像文件。这款软件对于那些希望在树莓派硬件上运行自定义操作系统或者进行系统备份的用户来说...

    win--eclipse3.4.2 安装VE插件所需插件(emf, gef ,ve)

    "win-eclipse3.4.2 安装VE插件所需插件(emf, gef, ve)"这个主题主要涉及到Eclipse中的三个关键插件:EMF( Eclipse Modeling Framework)、GEF(Graphical Editing Framework)和VE(Visual Editor)。 EMF是...

    Firefox火狐浏览器官方56.0-win32版本exe安装包

    2. 自定义搜索引擎:在地址栏右侧的下拉框中,你可以添加或更改默认搜索引擎,方便快速搜索。 3. 地址栏多功能:除了输入网址,你还可以在地址栏中直接进行搜索,或者输入如"about:config"查看和修改高级设置。 4....

    jeasyui-win-dlg1.zip_easy

    Easy UI则在此基础上构建了一系列的UI组件,如表格、下拉框、按钮、对话框等,使得开发者可以快速构建美观且功能丰富的Web应用。 对话框(dlg1)是jQuery Easy UI中的一个重要组件,常用于显示警告信息、获取用户...

    mfc中自绘ComboBox控件的美化有输入的历史记录

    然而,系统默认的ComboBox样式可能无法满足所有设计需求,因此,开发者有时需要对其进行自定义绘制,以实现更美观的效果。本项目中,我们讨论的就是如何在MFC中对ComboBox控件进行自绘美化,包括改变边框颜色、替换...

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

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

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

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

    win7自动换壁纸.rar

    然而,如果你想要更多自定义选项或者更灵活的控制,可以使用易语言编写的“win7自动换壁纸”程序。这个程序可能提供了以下功能: 1. 自定义更换频率:允许用户根据个人喜好设置更换壁纸的间隔时间,比如每小时、...

    win7从入门课程:怎么设置WIN7的桌面背景图片

    Windows 7提供了丰富的自定义选项,使这一过程变得既简单又有趣。 设置桌面背景的操作步骤如下: 1. **打开个性化设置**:右键点击桌面,从弹出菜单中选择“个性化”。这将打开“个性化”窗口,显示各种主题和背景...

    易语言-易语言自绘仿WIN10菜单

    本文将深入探讨“易语言自绘仿WIN10菜单”这一主题,帮助你理解如何在易语言中实现Windows 10风格的自定义菜单。 一、易语言基础 易语言的核心理念是“易学易用”,它的语法结构简洁明了,避免了传统编程语言中的...

    Win8默认输入法设置图解.docx

    - 有些第三方输入法还提供了自定义快捷键的功能,以便更方便地进行切换。 #### 六、总结 通过本文的介绍,我们详细了解了如何在Windows 8系统中将默认输入法从微软拼音简捷输入法更换为搜狗输入法或其他第三方...

    wincc 下拉菜单制作

    Set objGraphicView = HMIRuntime.Screens("PAX").ScreenItems("pic_win") MyString = Item.UserData objGraphicView.PictureName = MyString End Sub ``` - 在这个脚本中,当用户点击菜单项时,会根据菜单项...

    (整理)Windows界面设计标准 ..pdf

    - 空间有限时使用下拉框代替选项框,选项少时使用选项框,多时使用下拉列表框。 2. **规范性** - 小型软件不必强制提供工具栏,但常用菜单需有快捷键。 - 相似功能的菜单项用横线分隔,放置在同一位置。 - 菜单...

    自己写的一些帮助类库

    - **Win32API**:这部分代码可能使用了Windows操作系统提供的原生API函数,用于实现特定的系统级功能,如系统对话框、窗口管理等。 综合以上信息,这个类库集合是一个丰富的自定义组件资源,涵盖了UI界面设计、网络...

    FEA 中文前端框架 v1.4.0

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

    editplus格式化xml插件

    此外,EditPlus支持自定义XML的颜色主题和缩进样式,这可以在“环境”菜单的“颜色方案”和“文本缩进”选项中进行调整。根据个人喜好,你可以创建或导入不同的颜色方案,使得XML文件更加美观易读。 总的来说,...

    win7下保护眼睛,修改资源管理器背景颜色的方法

    然后在“颜色”下拉框中,选择“其他”以自定义颜色。 6. 设置背景颜色:此时会弹出一个新的“颜色”对话框。在色阶部分,将色调、饱和度和亮度调整到合适的值,以创建一种柔和的绿色。比如,你可以尝试将色调设置...

    win7下无需软件或adhoc补丁通过无线网卡搭建虚拟wifi网络.pdf

    在“共享”选项卡中,勾选“允许其他网络用户通过此计算机的Internet连接来连接”,并在下拉框中选择你刚刚创建的虚拟网卡。 4. 启动虚拟网络:返回命令提示符,输入: ``` netsh wlan start hostednetwork ``` ...

    win7下安装xp

    2. **添加启动项**:在EasyBCD的"添加新条目"中,选择"NT内核及更高版本",然后在"驱动器"下拉框中选择XP所在分区,点击"添加条目"。 3. **保存设置**:设置完成后,点击"保存设置",然后重启电脑。此时,启动时会...

Global site tag (gtag.js) - Google Analytics