《Windows程序设计》之菜单中使用位图

这几天没怎么学习,一直在改bug,做一个界面,也学到了很多,先发一篇,再去改界面bug。

LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam)
{
	HMENU hMenu;
	static int iCurrentFont=IDM_FONT_COUR;
	switch(iMsg)
	{
	case WM_CREATE:
		//把help加入到系统菜单中
		AddHelpToSys(((LPCREATESTRUCT)lParam)->hInstance,hwnd);
		//三个菜单项创建
		hMenu=CreateMyMenu(((LPCREATESTRUCT)lParam)->hInstance);
		//为窗口设置菜单hMenu
		SetMenu(hwnd,hMenu);
		//设置选中项
		CheckMenuItem(hMenu,iCurrentFont,MF_CHECKED);
		return 0;
	case WM_SYSCOMMAND:
		//系统菜单中的HELP操作
		switch(LOWORD(wParam))
		{
		case IDM_HELP:
			MessageBox(hwnd,TEXT("Help not yet implemented!"),szAppName,MB_OK|MB_ICONEXCLAMATION);
			return 0;
		}
		break;
	case WM_COMMAND:
		switch(LOWORD(wParam))
		{
		case IDM_FILE_NEW:
		case IDM_FILE_OPEN:
		case IDM_FILE_SAVE:
		case IDM_FILE_SAVE_AS:
		case IDM_EDIT_UNDO:
		case IDM_EDIT_CUT:
		case IDM_EDIT_COPY:
		case IDM_EDIT_PASTE:
		case IDM_EDIT_CLEAR:
			MessageBeep(0);
			return 0;
		//下面这部分与上一次一样,不多解释
		case IDM_FONT_COUR:
		case IDM_FONT_ARIAL:
		case IDM_FONT_TIMES:
			hMenu=GetMenu(hwnd);
			CheckMenuItem(hMenu,iCurrentFont,MF_UNCHECKED);
			iCurrentFont=LOWORD(wParam);
			CheckMenuItem(hMenu,iCurrentFont,MF_CHECKED);
			return 0;
		}
		break;
	case WM_DESTROY:
		//
		DeleteAllBitmaps(hwnd);
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd,iMsg,wParam,lParam);
}

void AddHelpToSys(HINSTANCE hInstance,HWND hwnd)
{
	HBITMAP hBitmap;
	HMENU hMenu;
	//访问窗口菜单,FALSE,则返回句柄,系统菜单
	hMenu=GetSystemMenu(hwnd,FALSE);
	//根据系统字体,对图片做一下缩放
	hBitmap=StretchBitmap(LoadBitmap(hInstance,TEXT("BITMAPHELP")));
	//增加水平线
	AppendMenu(hMenu,MF_SEPARATOR,0,NULL);
	//用位图作菜单项,hBitmap菜单项的内容
	AppendMenu(hMenu,MF_BITMAP,IDM_HELP,(PTSTR)(LONG)hBitmap);
}

HMENU CreateMyMenu(HINSTANCE hInstance)
{
	HBITMAP hBitmap;
	HMENU hMenu,hMenuPopup;
	int i;

	hMenu=CreateMenu();
	//载入菜单栏
	hMenuPopup=LoadMenu(hInstance,TEXT("MenuFile"));
	//BitmapFile做相应变换
	hBitmap=StretchBitmap(LoadBitmap(hInstance,TEXT("BitmapFile")));
	//hMenuPopup新菜单的标识,hBitmap新菜单的内容
	AppendMenu(hMenu,MF_BITMAP|MF_POPUP,(int)hMenuPopup,(PTSTR)(LONG)hBitmap);
	hMenuPopup=LoadMenu(hInstance,TEXT("MenuEdit"));
	hBitmap=StretchBitmap(LoadBitmap(hInstance,TEXT("BitmapEdit")));
	AppendMenu(hMenu,MF_BITMAP|MF_POPUP,(int)hMenuPopup,(PTSTR)(LONG)hBitmap);
	hMenuPopup=CreateMenu();
	for(i=0;i<3;i++)
	{
		//获取有相应文字的位图
		hBitmap=GetBitmapFont(i);
		//增加到菜单hMenuPopup中
		AppendMenu(hMenuPopup,MF_BITMAP,IDM_FONT_COUR+i,(PTSTR)(LONG)hBitmap);
	}
	//BitmapFont做相应变换
	hBitmap=StretchBitmap(LoadBitmap(hInstance,TEXT("BitmapFont")));
	//hMenuPopup增加到hMenu菜单中
	AppendMenu(hMenu,MF_BITMAP|MF_POPUP,(int)hMenuPopup,(PTSTR)(LONG)hBitmap);
	return hMenu;
}

HBITMAP StretchBitmap(HBITMAP hBitmap1)
{
	BITMAP bm1,bm2;
	HBITMAP hBitmap2;
	HDC hdc,hdcMem1,hdcMem2;
	int cxChar,cyChar;
	//系统中的字体平均宽度
	cxChar=LOWORD(GetDialogBaseUnits());
	//系统中的字体平均高度
	cyChar=HIWORD(GetDialogBaseUnits());
	//使用DISPLAY使用整个设备环境场景
	hdc=CreateIC(TEXT("DISPLAY"),NULL,NULL,NULL);
	//创建内存环境上下文环境
	hdcMem1=CreateCompatibleDC(hdc);
	hdcMem2=CreateCompatibleDC(hdc);
	DeleteDC(hdc);
	//得到整个图形对象的信息
	GetObject(hBitmap1,sizeof(BITMAP),(PTSTR)&bm1);
	//bm2的某些字段根据系统字体的大小做调整
	bm2=bm1;
	bm2.bmWidth=(cxChar*bm2.bmWidth)/4;
	bm2.bmHeight=(cyChar*bm2.bmHeight)/8;
	bm2.bmWidthBytes=((bm2.bmWidth+15)/16)*2;
	//创建一个新位图
	hBitmap2=CreateBitmapIndirect(&bm2);
	//选入两个设备环境中
	SelectObject(hdcMem1,hBitmap1);
	SelectObject(hdcMem2,hBitmap2);
	//把第一个复制到第二个位图中,完成缩放
	StretchBlt(hdcMem2,0,0,bm2.bmWidth,bm2.bmHeight,hdcMem1,0,0,bm1.bmWidth,bm1.bmHeight,SRCCOPY);
	//一些清理工作
	DeleteDC(hdcMem1);
	DeleteDC(hdcMem2);
	DeleteObject(hBitmap1);
	return hBitmap2;
}

HBITMAP GetBitmapFont(int i)
{
	static TCHAR * szFaceName[3]={TEXT("Courier New"),TEXT("Arial"),TEXT("Times New Roman")};
	HBITMAP hBitmap;
	HDC hdc,hdcMem;
	HFONT hFont;
	SIZE size;
	TEXTMETRIC tm;
	//获取整个屏幕的设备场景
	hdc=CreateIC(TEXT("DISPLAY"),NULL,NULL,NULL);
	//获取当前字体信息
	GetTextMetrics(hdc,&tm);
	//创建设备上下文
	hdcMem=CreateCompatibleDC(hdc);
	//字体高增加一倍
	hFont=CreateFont(2*tm.tmHeight,0,0,0,0,0,0,0,0,0,0,0,0,szFaceName[i]);
	//选入设备环境
	hFont=(HFONT)SelectObject(hdcMem,hFont);
	//正文字符串的高度和宽度
	GetTextExtentPoint32(hdcMem,szFaceName[i],lstrlen(szFaceName[i]),&size);
	//创建一个位图,与字符串大小相同的位图
	hBitmap=CreateBitmap(size.cx,size.cy,1,1,NULL);
	//选入设备环境
	SelectObject(hdcMem,hBitmap);
	//在内存中输入文字
	TextOut(hdcMem,0,0,szFaceName[i],lstrlen(szFaceName[i]));
	DeleteObject(SelectObject(hdcMem,hFont));
	DeleteDC(hdcMem);
	DeleteDC(hdc);
	return hBitmap;
}

void DeleteAllBitmaps(HWND hwnd)
{
	HMENU hMenu;
	int i;
	//菜单项结构体
	MENUITEMINFO mii={sizeof(MENUITEMINFO),MIIM_SUBMENU|MIIM_TYPE};
	//系统菜单
	hMenu=GetSystemMenu(hwnd,FALSE);
	//获取菜单相关信息
	GetMenuItemInfo(hMenu,IDM_HELP,FALSE,&mii);
	//删除相关信息
	DeleteObject((HBITMAP)mii.dwTypeData);
	//删除相关菜单
	hMenu=GetMenu(hwnd);
	for(i=0;i<3;i++)
	{
		GetMenuItemInfo(hMenu,i,TRUE,&mii);
		DeleteObject((HBITMAP)mii.dwTypeData);
	}
	//这是删除字体那一项中的子项
	hMenu=mii.hSubMenu;
	for(i=0;i<3;i++)
	{
		GetMenuItemInfo(hMenu,i,TRUE,&mii);
		DeleteObject((HBITMAP)mii.dwTypeData);
	}
}



你可能感兴趣的:(《Windows程序设计》之菜单中使用位图)