📄 mfc_api.txt
字号:
<1.32>如何显示资源中的256色位图?
由于256色位图在显示时需要改变显示DC的调色板,但LoadBitmap函数只能返
回一个DDB句柄,不能提供任何调色板信息。所以利用LoadBitmap无法正常装
入一个DIB资源供显示的。但我们可以利用FindResource,LoadResource,
LockResource等函数先将位图资源以DIB方式装入内存,再提取出调色板信息,
然后利用CreateDIBitmap函数将DIB位图转换为DDB位图。利用CreateDIBitmap
返回的句柄就可以用于BitBlt了。下面是例子代码:
HBITMAP LoadResourceBitmap(HINSTANCE hInstance,
LPSTR lpString/*资源名*/,
HPALETTE FAR* lphPalette/*调色板句柄指针*/)
{//这个函数用于替代LoadBitmap函数,只不过它另外生成一个调色板句柄
HRSRC hRsrc;HDC hdc;
HGLOBAL hGlobal;
HBITMAP hBitmapFinal = NULL;
LPBITMAPINFOHEADER lpbi;
int iNumColors;//调色板中的颜色数目
if (hRsrc = FindResource(hInstance, lpString, RT_BITMAP))
{//如何找到了相应的资源
hGlobal = LoadResource(hInstance, hRsrc);//装入资源
lpbi = (LPBITMAPINFOHEADER)LockResource(hGlobal);//锁定资源
*lphPalette = CreateDIBPalette ((LPBITMAPINFO)lpbi, &iNumColors);
//从资源中生成调色板
hdc=GetDC(NULL);//获取当前显示DC
hBitmapFinal =
CreateDIBitmap(hdc,(LPBITMAPINFOHEADER)lpbi,(LONG)CBM_INIT,
(LPSTR)lpbi+lpbi->biSize+iNumColors *sizeof(RGBQUAD),//指向位图数据
(LPBITMAPINFO)lpbi,DIB_RGB_COLORS );//将DIB位图(存在hGlobal)转换为
//与hDC相兼容的DDB句柄
ReleaseDC(NULL,hdc);
UnlockResource(hGlobal);
FreeResource(hGlobal);
}
return (hBitmapFinal);
}
HPALETTE CreateDIBPalette (LPBITMAPINFO lpbmi, LPINT lpiNumColors)
{//该函数从DIB位图的数据结构中获取该位图的调色板和颜色的数目
LPBITMAPINFOHEADER lpbi;
LPLOGPALETTE lpPal;
HANDLE hLogPal;
HPALETTE hPal = NULL;
int i;
lpbi = (LPBITMAPINFOHEADER)lpbmi;
if (lpbi->biBitCount <= 8)
*lpiNumColors = (1 << lpbi->biBitCount);
else
*lpiNumColors = 0; // 如果是真彩色位图则不需要调色板
if (*lpiNumColors)
{//如果需要调色板
//分配生成调色板所需要的数据结构
hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
sizeof (PALETTEENTRY) * (*lpiNumColors));
lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
lpPal->palVersion = 0x300;//设置板本为0x300
lpPal->palNumEntries = *lpiNumColors;//调色板的颜色数
for (i = 0; i < *lpiNumColors; i++)
{
lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}//从DIB数据结构中向调色板数据结构中传输调色板数据
hPal = CreatePalette (lpPal);//生成调色板句柄
GlobalUnlock (hLogPal);
GlobalFree (hLogPal);
}
return hPal;
}
下面的代码是利用LoadResourceBitmap函数返回的位图句柄和调色板
句柄来显示DIB位图:
HBITMAP hBitmap,hOldBitmap;
HPALETTE hPalette;
HDC hMemDC, hdc;
BITMAP bm;
hBitmap = LoadResourceBitmap(hInst,"test", &hPalette);
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
hdc = GetDC(hWnd);
hMemDC = CreateCompatibleDC(hdc);
SelectPalette(hdc,hPalette,FALSE);//将调色板选入DC
RealizePalette(hdc);//完成逻辑调色板向系统调色板的映射
SelectPalette(hMemDC,hPalette,FALSE);//内存DC中的调色板应该与
//显示DC的相同
RealizePalette(hMemDC);
hOldBitmap = SelectObject(hMemDC,hBitmap);
BitBlt(hdc,0,0,bm.bmWidth,bm.bmHeight,hMemDC,0,0,SRCCOPY);
DeleteObject(SelectObject(hMemDC,hOldBitmap));
DeleteDC(hMemDC);
ReleaseDC(hWnd,hdc);
DeleteObject(hPalette);
<1.33>MFC有哪些自定义的消息?
下面介绍的这些消息(不是全部)定义在AFXPRIV.H中(VC4.0中是这样,
以后的版本可能会改变),可以用ON_MESSAGE宏来定义消息映射。我们可以
利用这些消息来实现一些特定的功能。
<1>WM_QUERYAFXWNDPROC
wParam Not used
lParam Not used
这个消息在窗口生成阶段早期发送给窗口函数的,用于判断窗口函数是
否是AFxWndProc。
AfxWndProc返回1
<2>WM_SIZEPARENT
wParam Not used
lParam 是指向AFX_SIZEPARENTPARAMS的指针
returns Not used(0)
这个消息是框架窗口在窗口大小改变时发送给子窗口,用于调整各种控制
条(control bars)位置的(CFrameWnd::OnSize调用CFrameWnd::RecalcLayout
函数,而该函数又调用CWnd::RepositionBars函数)。AFX_SIZEPARENTPARAMS
结构中包含有当前父窗口的客户区域和用于调用DeferWindowPos的HDWP成员。
如果忽略这个消息则表明不参与框架窗口客户区的布局。
<3>WM_SETMESSAGESTRING
wParam 字符串ID或0
lParam LPCSTR或0
returns Not Used(0)
向框架窗口发送这个消息通知框架窗口更新状态条的显示信息。
wParam和lParam不能同时包含有效数据。
<4>WM_IDLEUPDATECMDUI
wParam BOOL //bDisableIfNoHandler,如果为TRUE,表明
//该窗口不处理这个消息时,就禁止相应的菜单或按钮。
lParam Not used (0)
returns Not used (0)
这个消息是在应用程序空闲时才发往窗口(主要是各种控制条)的,用于实
现菜单使能、控制条按钮禁止等功能。如果控制条窗口选择处理这个消息,
它必须生成一个CCMDUI对象并调用CCmdUI::DoUpdate函数来更新菜单或按
钮状态。
<5>WM_EXITHELPMODE
wParam Not used (0)
lParam Not used (0)
returns Not used
这个消息Post到框架窗口中使窗口退出上下文敏感帮助模式(context
sensitive help mode)。
<6>WM_INITIALUPDATE
wParam Not used (0)
lParam Not used (0)
returns Not used (0)
这个消息是由文档模板发送到所有的框架窗口的子窗口的,通知它们可以进
行初始化(initial update)了。比如,视类的OnInitialUpdate函数。
<7>WM_RECALCPARENT
wParam Not used (0)
lParam LPRECT
returns BOOL//如果是lParam返回的是新的客户区域那么返回TRUE,否则
//为FALSE通常一个视可以向父框架窗口发送(send)这个消息来强制父窗口
//重新安排客户区的布局(父窗口通常调用RecalcLayout函数)。如果一个
//OLE server需要根据视新的大小要求框架窗口改变布局时就可以利用这
//个消息。
<8>WM_DISABLEMODAL
wParam Not used (0)
lParam Not used (0)
returns 如果是非零,则不能禁止相应的弹出式窗口
当框架窗口即将变为非活动状态(deactivated)时,所有属于该框架窗口的
弹出式窗口都会收到这个消息。框架窗口根据消息的返回值来决定是否要禁
止那些弹出式窗口。
我们可以利用这个消息在框架窗口进入modal状态(比如弹出模态对话框时)
或想一直保持一些弹出式窗口活动状态时,做一些特别的处理。比如,
Tooltips控件就利用这个消息来撤消自己。
<9>WM_QUERY3DCONTROLS
wParam Not used (0)
lParam Not used (0)
returns 如果非零则表明可以用CTL3D来subclass
在窗口生成期间,这个消息会发送给窗口来决定该窗口是否应该
被CTL3D32.DLL subclassed。通常CControlBar,CDialog,
CPropertySheet,CFormView都返回TRUE。
<1.34>如何在状态条中显示位图 ?
1.从CStatusBar派生一个类并重载DoPaint函数。
2.在DoPaint函数中,使用BitBlt函数将位图拷贝到特定的状态条pane。
void CMyStatusBar::DoPaint(CDC* pDC)
{
CRect rect;
GetItemRect(INDEX_PANE1, &rect); // 获得相应pane的矩形区域
pDC->ExcludeClipRect(&rect); // 将这个区域从剪切区域中除去
CStatusBar::DoPaint(pDC); // 调用基类的DoPaint,完成其它区域的重画
CRgn paneRgn;
paneRgn.CreateRectRgnIndirect(rect);
pDC->SelectClipRgn(&paneRgn); // 将放置位图的区域设置为剪切区域
CBitmap* pBitmap=new CBitmap;
装入要显示的位图
CDC srcDC;
srcDC.CreateCompatibleDC(NULL);//生成与当前显示DC相兼容的内存DC
CBitmap* pOldBitmap = srcDC.SelectObject(pBitmap);//将要显示的位
//图选入这个内存DC
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&srcDC, 0, 0, SRCCOPY); // 拷贝位图
srcDC.SelectObject(pOldBitmap);//恢复原位图选择,这是必须的,否则
//这个内存DC无法删除
}
<1.35>如何在状态条中显示当前时间?
1.生成一个字符串资源,比如名为ID_INDICATOR_TIME的字符串是00:00。
状态条可以利用这些字符串长度来确定相应pane的大小。当然应用程序可
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -