1. 如何激活當前屏幕保護程序
// 激活當前屏幕保護程序, jingzhou xu
PostMessage(WM_SYSCOMMAND,SC_SCREENSAVE,0);
2. 如何禁止/啟用屏幕保護及電源管理
static UINT dss_GetList[] = {SPI_GETLOWPOWERTIMEOUT, SPI_GETPOWEROFFTIMEOUT, SPI_GETSCREENSAVETIMEOUT};
static UINT dss_SetList[] = {SPI_SETLOWPOWERTIMEOUT, SPI_SETPOWEROFFTIMEOUT, SPI_SETSCREENSAVETIMEOUT};
static const int dss_ListCount = _countof(dss_GetList);
l 禁止屏幕保護及電源管理
{
m_pValue = new int[dss_ListCount];
for (int x=0;x<dss_ListCount;x++)
{
// 禁止屏幕保護及電源管理
VERIFY(SystemParametersInfo (dss_SetList[x], 0, NULL, 0));
}
delete[] m_pValue;
}
l 啟用屏幕保護及電源管理
{
m_pValue = new int[dss_ListCount];
for (int x=0;x<dss_ListCount;x++)
{
//啟用屏幕保護及電源管理
VERIFY(SystemParametersInfo (dss_SetList[x], m_pValue[x], NULL, 0));
}
delete[] m_pValue;
}
3. 如何激活和關(guān)閉IE瀏覽器
//激活并打開IE
void lounchIE()
{
HWND h=FindWindowEx(NULL,NULL,NULL,
"Microsoft Internet Explorer") ;
ShellExecute(h,"open","C:\\simple.html",
NULL,NULL,SW_SHOWNORMAL);
}
//關(guān)閉IE及其它應(yīng)用
void CloseIE()
{
int app=BSM_APPLICATIONS;
unsigned long bsm_app=(unsigned long )app;
BroadcastSystemMessage(BSF_POSTMESSAGE,&bsm_app,
WM_CLOSE,NULL,NULL);
}
4. 如何給樹控件加入工具提示
l 首先給樹控件加入TVS_INFOTIP屬性風格,如下所示:
if (!m_ctrlTree.Create(WS_CHILD|WS_VISIBLE|
TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT|TVS_SHOWSELALWAYS|TVS_INFOTIP, //加入提示TVS_INFOTIP,jingzhou xu(樹控件ID:100)
CRect(0, 0, 0, 0), &m_wndTreeBar, 100))
{
TRACE0("Failed to create instant bar child\n");
return -1;
}
l 其次加入映射消息聲明,如下所示:
afx_msg void OnGetInfoTip(NMHDR* pNMHDR,LRESULT* pResult); //樹控件上加入提示消息,jingzhou xu
ON_NOTIFY(TVN_GETINFOTIP, 100, OnGetInfoTip) //樹控件條目上加入提示,jingzhou xu
l 最后加入呼應(yīng)涵數(shù)處理:
void CCreateTreeDlg::OnGetInfoTip(NMHDR* pNMHDR,
LRESULT* pResult)
{
*pResult = 0;
NMTVGETINFOTIP* pTVTipInfo = (NMTVGETINFOTIP*)pNMHDR;
LPARAM itemData = (DWORD) pTVTipInfo->lParam;
//對應(yīng)每個條目的數(shù)據(jù)
HTREEITEM hItem = pTVTipInfo->hItem;
CString tip;
HTREEITEM hRootItem = m_chassisTree.GetRootItem();
if (hRootItem != pTVTipInfo->hItem)
{
tip = "樹結(jié)點的提示";
}
else
{
tip = "樹根上的提示";
}
strcpy(pTVTipInfo->pszText, (LPCTSTR) tip);
}
5. 如何獲取系統(tǒng)信息框的路徑
#include <atlbase.h>
#define IDS_REG_KEY_MSINFO_PATH1 _T( "Software\\Microsoft\\Shared Tools\\MSInfo" )
#define IDS_REG_KEY_MSINFO_PATH2 _T( "Software\\Microsoft\\Shared Tools Location" )
#define IDS_REG_VAL_MSINFO_PATH1 _T( "Path" )
#define IDS_REG_VAL_MSINFO_PATH2 _T( "MSInfo" )
#define IDS_MSINFO_EXE_NAME _T( "MSInfo32.exe" )
//...
BOOL GetSysInfoPath( CString& strPath )
{
strPath.Empty();
LPTSTR pszPath = strPath.GetBuffer( MAX_PATH );
CRegKey reg;
DWORD dwSize = MAX_PATH;
LONG nRet = reg.Open( HKEY_LOCAL_MACHINE, IDS_REG_KEY_MSINFO_PATH1, KEY_READ );
// 在注冊表中尋找第一個"MSInfo32.exe" 位置
if ( nRet == ERROR_SUCCESS )
{
#if ( _MFC_VER >= 0x0700 )
nRet = reg.QueryStringValue( IDS_REG_VAL_MSINFO_PATH1, pszPath, &dwSize );
#else
nRet = reg.QueryValue( pszPath, IDS_REG_VAL_MSINFO_PATH1, &dwSize );
#endif
reg.Close();
}
// 如果第一次尋找失敗,則進行第二次尋找
if ( nRet != ERROR_SUCCESS )
{
nRet = reg.Open( HKEY_LOCAL_MACHINE, IDS_REG_KEY_MSINFO_PATH2, KEY_READ );
if ( nRet == ERROR_SUCCESS )
{
#if ( _MFC_VER >= 0x0700 )
reg.QueryStringValue( IDS_REG_VAL_MSINFO_PATH2, pszPath, &dwSize );
#else
reg.QueryValue( pszPath, IDS_REG_VAL_MSINFO_PATH2, &dwSize );
#endif
// 路徑名不包括EXE文件名
if ( nRet == ERROR_SUCCESS )
VERIFY( ::PathAppend( pszPath, IDS_MSINFO_EXE_NAME ) );
reg.Close();
}
}
strPath.ReleaseBuffer();
strPath.FreeExtra();
// 檢查文件是否有效.
return ::PathFileExists( strPath );
}
6. 如何直接運行一個資源中的程序
bool Run()
{
CFile f;
char* pFileName = "Execution.exe";
if( !f.Open( pFileName, CFile::modeCreate | CFile::modeWrite, NULL ) )
{
AfxMessageBox("Can not create file!");
return 0;
}
CString path = f.GetFilePath();
HGLOBAL hRes;
HRSRC hResInfo;
//獲取應(yīng)用實例
HINSTANCE insApp = AfxGetInstanceHandle();
//尋找EXE資源名
hResInfo = FindResource(insApp,(LPCSTR)IDR_EXE4,"EXE");
hRes = LoadResource(insApp,hResInfo ); // Load it
DWORD dFileLength = SizeofResource( insApp, hResInfo ); //計算EXE文件大小
f.WriteHuge((LPSTR)hRes,dFileLength); //寫入臨時文件
f.Close();
HINSTANCE HINSsd = ShellExecute(NULL, "open",path, NULL, NULL, SW_SHOWNORMAL);> //運行它.
return 1;
}
7. 如何遍歷整個目錄
#include <windows.h>
#include <shlobj.h>
//瀏覽目錄.
void BrowseFolder( void )
{
TCHAR path[MAX_PATH];
BROWSEINFO bi = { 0 };
bi.lpszTitle = ("遞歸調(diào)用所有目錄");
LPITEMIDLIST pidl = SHBrowseForFolder ( &bi );
if ( pidl != 0 )
{
// 獲取目錄路徑
SHGetPathFromIDList ( pidl, path );
//設(shè)置為當前路徑
SetCurrentDirectory ( path );
//搜索所有子目錄
SearchFolder( path );
// 釋放內(nèi)存
IMalloc * imalloc = 0;
if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )
{
imalloc->Free ( pidl );
imalloc->Release ( );
}
}
//搜索其下所有子目錄及文件.
void SearchFolder( TCHAR * path )
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
TCHAR filename[ MAX_PATH + 256 ];
TCHAR pathbak[ MAX_PATH ];
//復(fù)制初始用戶選擇目錄
strcpy( pathbak, path );
//尋找第一個文件
hFind = FindFirstFile ( "*.*", &FindFileData );
//搜索所有文件及子目錄
do
{
if ( hFind != INVALID_HANDLE_VALUE )
{
//如果是當前目錄或父目錄,跳過
if ( ! ( strcmp( FindFileData.cFileName, "." ) ) || ! ( strcmp( FindFileData.cFileName, ".." ) ) )
{
continue;
}
//恢復(fù)初始用戶選擇目錄
strcpy( path, pathbak );
//列出所有發(fā)現(xiàn)的文件
sprintf( path, "%s\\%s", path, FindFileData.cFileName );
//如果 SetCurrentDirectory 成功的話,則它是一個目錄,遞歸調(diào)用繼續(xù)搜索子目錄
if ( ( SetCurrentDirectory( path ) ) )
{
SearchFolder( path );
}
//插入文件及路徑名到列表框m_listbox_hwnd中
SendMessage( m_listbox_hwnd, LB_ADDSTRING, 0, path ); //<--INSERT WHAT YOU WANT DONE HERE!
}
}
while ( FindNextFile ( hFind, &FindFileData ) && hFind != INVALID_HANDLE_VALUE );
FindClose ( hFind );
}
8. 如何禁止/啟用系統(tǒng)熱鍵
bool bOld;
l 禁止系統(tǒng)熱鍵
//屏蔽掉系統(tǒng)鍵
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,true,&bOld,SPIF_UPDATEINIFILE);
l 啟用系統(tǒng)熱鍵
//恢復(fù)系統(tǒng)熱鍵
SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,false,&bOld,SPIF_UPDATEINIFILE);
9. 如何隱藏/顯示W(wǎng)INDOWS系統(tǒng)任務(wù)欄
l 隱藏系統(tǒng)任務(wù)欄
//隱藏WINDOWS系統(tǒng)任務(wù)欄
::ShowWindow (::FindWindow("Shell_TrayWnd",NULL),SW_HIDE);
l 顯示系統(tǒng)任務(wù)欄
//恢復(fù)WINDOWS系統(tǒng)任務(wù)欄正常顯示
::ShowWindow (::FindWindow("Shell_TrayWnd",NULL),SW_SHOW);
10. 如何實現(xiàn)窗口到系統(tǒng)區(qū)圖標間的動畫效果
//********************************************************************************
//* 名稱:FindTrayWnd
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:在顯示窗體動畫效果前,先尋找系統(tǒng)區(qū)位置
//********************************************************************************
BOOL CALLBACK FindTrayWnd(HWND hwnd, LPARAM lParam)
{
TCHAR szClassName[256];
GetClassName(hwnd, szClassName, 255);
// 比較窗口類名
if (_tcscmp(szClassName, _T("TrayNotifyWnd")) == 0)
{
CRect *pRect = (CRect*) lParam;
::GetWindowRect(hwnd, pRect);
return TRUE;
}
// 當找到時鐘窗口時表示可以結(jié)束了
if (_tcscmp(szClassName, _T("TrayClockWClass")) == 0)
{
CRect *pRect = (CRect*) lParam;
CRect rectClock;
::GetWindowRect(hwnd, rectClock);
pRect->right = rectClock.left;
return FALSE;
}
return TRUE;
}
//********************************************************************************
//* 名稱:WinAnimation
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:顯示窗口動畫效果的涵數(shù)
//********************************************************************************
void CScreenSnapDlg::WinAnimation(BOOL ShowFlag)
{
CRect rect(0,0,0,0);
// 查找托盤窗口
CWnd* pWnd = FindWindow("Shell_TrayWnd", NULL);
if (pWnd)
{
pWnd->GetWindowRect(rect);
EnumChildWindows(pWnd->m_hWnd, FindTrayWnd, (LPARAM)&rect);
//rect 為托盤區(qū)矩形
CRect rcWnd;
GetWindowRect(rcWnd);
if(ShowFlag) //窗體滑向系統(tǒng)區(qū)
DrawAnimatedRects(GetSafeHwnd(),IDANI_CAPTION,rcWnd,rect);
else //窗體從系統(tǒng)區(qū)滑出
DrawAnimatedRects(GetSafeHwnd(),IDANI_CAPTION,rect,rcWnd);
}
}
用法如下:
if(IsWindowVisible()) //窗體是否已隱藏
{
ShowWindow(SW_HIDE); //先隱藏窗體
WinAnimation(true); //窗體動畫滑入到系統(tǒng)區(qū)中
}
else
{
WinAnimation(false); //窗體動畫從系統(tǒng)區(qū)滑出
ShowWindow(SW_SHOW);
}
11. 如何判斷當前操作系統(tǒng)的版本
//------------------------------------------------------------------------------------------------
//判斷操作系統(tǒng)涵數(shù)及變量,jingzhou xu
typedef enum tagWin32SysType{
Windows32s,
WindowsNT3,
Windows95,
Windows98,
WindowsME,
WindowsNT4,
Windows2000,
WindowsXP
}Win32SysType;
//判斷操作系統(tǒng)涵數(shù)及變量,jingzhou xu
Win32SysType IsShellSysType()
{
Win32SysType ShellType;
DWORD winVer;
OSVERSIONINFO *osvi;
winVer=GetVersion();
if(winVer<0x80000000){/*NT */
ShellType=WindowsNT3;
osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
if (osvi!=NULL){
memset(osvi,0,sizeof(OSVERSIONINFO));
osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(osvi);
if(osvi->dwMajorVersion==4L)ShellType=WindowsNT4;
else if(osvi->dwMajorVersion==5L&&osvi->dwMinorVersion==0L)ShellType=Windows2000;
else if(osvi->dwMajorVersion==5L&&osvi->dwMinorVersion==1L)ShellType=WindowsXP;
free(osvi);
}
}
else if (LOBYTE(LOWORD(winVer))<4)
ShellType=Windows32s;
else{
ShellType=Windows95;
osvi= (OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
if (osvi!=NULL){
memset(osvi,0,sizeof(OSVERSIONINFO));
osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
GetVersionEx(osvi);
if(osvi->dwMajorVersion==4L&&osvi->dwMinorVersion==10L)ShellType=Windows98;
else if(osvi->dwMajorVersion==4L&&osvi->dwMinorVersion==90L)ShellType=WindowsME;
free(osvi);
}
}
return ShellType;
}
//------------------------------------------------------------------------------------------------
12. 如何在指定矩形框內(nèi)水平/垂直顯示多行文字
///////////////////////////////////////////////////////
//說明:
// 在矩形框中水平或垂直顯示多行文字,jingzhou xu.
// lMode: 排列方式,0:水平方式; 1:垂直對齊
// lHori: 水平對齊方式, 0:左對齊; 1:居中; 2:右對齊; 3:自定義
// lVert: 垂直對齊方式, 0:頂對齊; 1:居中; 2:底對齊; 3:自定義
///////////////////////////////////////////////////////
CRect DrawTitleInRect(CDC *pDC, CString szString, LPRECT lpRect, long lMode, long lHori, long lVert)
{
TEXTMETRIC tm;
pDC->GetTextMetrics(&tm);
int tmpWidth=tm.tmAveCharWidth, tmpHeight=tm.tmHeight;
CRect rcInner(lpRect);
if(lMode==0)
{
rcInner.left+=tmpWidth;
rcInner.right-=tmpWidth;
rcInner.top-=tmpWidth;
rcInner.bottom+=tmpWidth;
}
if(lMode==1)
{
rcInner.left+=tmpWidth;
rcInner.right=rcInner.left+tmpWidth;
rcInner.top-=tmpWidth;
rcInner.bottom+=tmpWidth;
}
pDC->DrawText(szString, rcInner,DT_CALCRECT);
switch(lHori)
{
case 0:
break;
case 1:
{
long xOutCent=(lpRect->right+lpRect->left)/2;
long xInnCent=(rcInner.right+rcInner.left)/2;
rcInner.left+=(xOutCent-xInnCent);
rcInner.right+=(xOutCent-xInnCent);
}
break;
case 2:
{
long lInWidth=rcInner.right-rcInner.left;
rcInner.right=lpRect->right-tmpWidth;
rcInner.left=rcInner.right-lInWidth;
}
break;
default:
break;
}
switch(lVert)
{
case 0:
break;
case 1:
{
long yOutCent=(lpRect->bottom+lpRect->top)/2;
long yInnCent=(rcInner.bottom+rcInner.top)/2;
rcInner.top-=(yInnCent-yOutCent);
rcInner.bottom-=(yInnCent-yOutCent);
}
break;
case 2:
{
long lInHeigh=rcInner.top-rcInner.bottom;
rcInner.bottom=lpRect->bottom+tmpWidth;
rcInner.top=rcInner.bottom+lInHeigh;
}
break;
default:
break;
}
//---------------------------------------------------------------------------------------------
//功能:根據(jù)新、老矩形,重新計算行數(shù),使文字多行顯示,jingzhou xu
//---------------------------------------------------------------------------------------------
//一行中最大字符數(shù)
int nMaxLineChar = abs(lpRect->right - lpRect->left) / tmpWidth ;
//記錄當前行的寬度
short theLineLength=0;
//記錄當前行中漢字字節(jié)數(shù),以防止將一半漢字分為兩行
unsigned short halfChinese=0;
for(int i=0; i<=szString.GetLength()-1; i++)
{
if(((unsigned char)szString.GetAt(i) == 0x0d) && ((unsigned char)szString.GetAt(i+1) == 0x0a))
theLineLength=0;
//大于0xa1的字節(jié)為漢字字節(jié)
if((unsigned char)szString.GetAt(i) >= 0xA1)
halfChinese++;
theLineLength++;
//如果行寬大于每行最大寬度,進行特殊處理
if(theLineLength > nMaxLineChar)
{
//防止將一個漢字分為兩行,回溯
if(halfChinese%2)
{
szString.Insert(i,(unsigned char)0x0a);
szString.Insert(i,(unsigned char)0x0d);
}
else
{
szString.Insert(i-1,(unsigned char)0x0a);
szString.Insert(i-1,(unsigned char)0x0d);
}
theLineLength = 0;
}
}
//重新計算矩形邊界范圍
// int tmpLine = int(abs(szString.GetLength()*tmpWidth / abs(lpRect->right - lpRect->left)-0.5));
// tmpLine += (szString.GetLength()*tmpWidth % abs(lpRect->right - lpRect->left))? 1 : 0;
// if(tmpLine == 0)
// tmpLine = 1;
if(rcInner.bottom > lpRect->bottom)
rcInner.bottom = lpRect->bottom;
if(rcInner.top < lpRect->top)
rcInner.top = lpRect->top;
//---------------------------------------------------------------------------------------------
if(lHori==0)
pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_LEFT);
else if(lHori==1)
pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_CENTER);
else if(lHori==2)
pDC->DrawText(szString, rcInner, DT_WORDBREAK|DT_RIGHT);
return rcInner;
}
13. 如何在指定矩形中旋轉(zhuǎn)顯示文字
///////////////////////////////////////////////////////
//說明:
// 在矩形框中旋轉(zhuǎn)方式顯示文字,jingzhou xu
//參數(shù):
// pDC: DC指針
// str: 顯示文字
// rect: 顯示范圍
// angle: 旋轉(zhuǎn)角度
// nOptions: ExtTextOut()中相應(yīng)設(shè)置<ETO_CLIPPED 和 ETO_OPAQUE>
///////////////////////////////////////////////////////
void DrawRotatedText(CDC* pDC, const CString str, CRect rect,
double angle, UINT nOptions)
{
//按比例轉(zhuǎn)換角度值
double pi = 3.141592654;
double radian = pi * 2 / 360 * angle;
//獲取顯示文字中心點
CSize TextSize = pDC->GetTextExtent(str);
CPoint center;
center.x = TextSize.cx / 2;
center.y = TextSize.cy / 2;
//計算顯示文字新的中心點
CPoint rcenter;
rcenter.x = long(cos(radian) * center.x - sin(radian) * center.y);
rcenter.y = long(sin(radian) * center.x + cos(radian) * center.y);
//繪制文字
pDC->SetTextAlign(TA_BASELINE);
pDC->SetBkMode(TRANSPARENT);
pDC->ExtTextOut(rect.left + rect.Width() / 2 - rcenter.x,
rect.top + rect.Height() / 2 + rcenter.y,
nOptions, rect, str, NULL);
}
14. 如何將32 x 32像素圖標轉(zhuǎn)換為16 x 16像素值的圖標
HICON Convert32x32IconTo16x16(HICON h32x32Icon)
{
HDC hMainDC, hMemDC1, hMemDC2;
HICON h16x16Icon;
BITMAP bmp;
HBITMAP hOldBmp1, hOldBmp2;
ICONINFO IconInfo32x32, IconInfo16x16;
GetIconInfo(h32x32Icon, &IconInfo32x32);
hMainDC = ::GetDC(m_hWnd);
hMemDC1 = CreateCompatibleDC(hMainDC);
hMemDC2 = CreateCompatibleDC(hMainDC);
GetObject(IconInfo32x32.hbmColor, sizeof(BITMAP), &bmp);
IconInfo16x16.hbmColor = CreateBitmap( 16, 16,
bmp.bmPlanes,
bmp.bmBitsPixel,
NULL);
hOldBmp1 = (HBITMAP) SelectObject( hMemDC1,
IconInfo32x32.hbmColor);
hOldBmp2 = (HBITMAP) SelectObject( hMemDC2,
IconInfo16x16.hbmColor);
StretchBlt(hMemDC2,
0, 0,
16, 16,
hMemDC1,
0, 0,
32, 32,
SRCCOPY
);
GetObject(IconInfo32x32.hbmMask, sizeof(BITMAP), &bmp);
IconInfo16x16.hbmMask = CreateBitmap( 16, 16,
bmp.bmPlanes,
bmp.bmBitsPixel,
NULL);
SelectObject(hMemDC1, IconInfo32x32.hbmMask);
SelectObject(hMemDC2, IconInfo16x16.hbmMask);
StretchBlt(hMemDC2,
0, 0,
16, 16,
hMemDC1,
0, 0,
32, 32,
SRCCOPY
);
SelectObject(hMemDC1, hOldBmp1);
SelectObject(hMemDC2, hOldBmp2);
IconInfo16x16.fIcon = TRUE;
h16x16Icon = CreateIconIndirect(&IconInfo16x16);
DeleteObject(IconInfo32x32.hbmColor);
DeleteObject(IconInfo16x16.hbmColor);
DeleteObject(IconInfo32x32.hbmMask);
DeleteObject(IconInfo16x16.hbmMask);
DeleteDC(hMemDC1);
DeleteDC(hMemDC2);
::ReleaseDC(m_hWnd, hMainDC);
return h16x16Icon;
}
15. 如何建立一個灰度級圖標
HICON CreateGrayscaleIcon(HICON hIcon)
{
HICON hGrayIcon = NULL;
HDC hMainDC = NULL,
hMemDC1 = NULL,
hMemDC2 = NULL;
BITMAP bmp;
HBITMAP hOldBmp1 = NULL,
hOldBmp2 = NULL;
ICONINFO csII, csGrayII;
BOOL bRetValue = FALSE;
bRetValue = ::GetIconInfo(hIcon, &csII);
if (bRetValue == FALSE) return NULL;
hMainDC = ::GetDC(m_hWnd);
hMemDC1 = ::CreateCompatibleDC(hMainDC);
hMemDC2 = ::CreateCompatibleDC(hMainDC);
if (hMainDC == NULL ||
hMemDC1 == NULL ||
hMemDC2 == NULL)
return NULL;
if (::GetObject(csII.hbmColor,
sizeof(BITMAP), &
amp;bmp))
{
csGrayII.hbmColor =
::CreateBitmap(csII.xHotspot*2,
csII.yHotspot*2,
bmp.bmPlanes,
bmp.bmBitsPixel,
NULL);
if (csGrayII.hbmColor)
{
hOldBmp1 =
(HBITMAP)::SelectObject(hMemDC1,
csII.hbmColor);
hOldBmp2 =
(HBITMAP)::SelectObject(hMemDC2,
csGrayII.hbmColor);
::BitBlt(hMemDC2, 0, 0, csII.xHotspot*2,
csII.yHotspot*2, hMemDC1, 0, 0,
SRCCOPY);
DWORD dwLoopY = 0, dwLoopX = 0;
COLORREF crPixel = 0;
BYTE byNewPixel = 0;
for (dwLoopY = 0; dwLoopY < csII.yHotspot*2; dwLoopY++)
{
for (dwLoopX = 0; dwLoopX < csII.xHotspot*2; dwLoopX++)
{
crPixel = ::GetPixel(hMemDC2, dwLoopX, dwLoopY);
byNewPixel = (BYTE)((GetRValue(crPixel) * 0.299) +
(GetGValue(crPixel) * 0.587) +
(GetBValue(crPixel) * 0.114));
if (crPixel) ::SetPixel(hMemDC2,
dwLoopX,
dwLoopY,
RGB(byNewPixel,
byNewPixel,
byNewPixel));
} // for
} // for
::SelectObject(hMemDC1, hOldBmp1);
::SelectObject(hMemDC2, hOldBmp2);
csGrayII.hbmMask = csII.hbmMask;
csGrayII.fIcon = TRUE;
hGrayIcon = ::CreateIconIndirect(&csGrayII);
} // if
::DeleteObject(csGrayII.hbmColor);
//::DeleteObject(csGrayII.hbmMask);
} // if
::DeleteObject(csII.hbmColor);
::DeleteObject(csII.hbmMask);
::DeleteDC(hMemDC1);
::DeleteDC(hMemDC2);
::ReleaseDC(m_hWnd, hMainDC);
return hGrayIcon;
}
16. 如何按指定角度旋轉(zhuǎn)顯示內(nèi)存位圖(用法和BitBlt類似)
void RotBlt(HDC destDC, int srcx1, int srcy1, int srcx2, int srcy2,
HDC srcDC , int destx1, int desty1 ,int thetaInDegrees ,DWORD mode)
{
double theta = thetaInDegrees * (3.14159/180);
//原圖像原始大小
int width = srcx2 - srcx1;
int height = srcy2 - srcy1;
//原圖像中心點
int centreX = int(float(srcx2 + srcx1)/2);
int centreY = int(float(srcy2 + srcy1)/2);
//判斷出圖像可以沿任意方向旋轉(zhuǎn)的矩形框
if(width>height)height = width;
else
width = height;
HDC memDC = CreateCompatibleDC(destDC);
HBITMAP memBmp = CreateCompatibleBitmap(destDC, width, height);
HBITMAP obmp = (HBITMAP) SelectObject(memDC, memBmp);
//內(nèi)存DC新在中心點
int newCentre = int(float(width)/2);
//開始旋轉(zhuǎn)
for(int x = srcx1; x<=srcx2; x++)
for(int y = srcy1; y<=srcy2; y++)
{
COLORREF col = GetPixel(srcDC,x,y);
int newX = int((x-centreX)*sin(theta)+(y-centreY)*cos(theta));
int newY = int((x-centreX)*cos(theta)-(y-centreY)*sin(theta));
SetPixel(memDC , newX + newCentre, newY + newCentre, col);
}
//復(fù)制到目標DC上
BitBlt(destDC, destx1, desty1, width, height, memDC, 0,0,mode);
//釋放內(nèi)存
SelectObject(memDC, obmp);
DeleteDC(memDC);
DeleteObject(memBmp);
}
用法:
RotBlt(dc, 0,0,150,150,memDC,200,0, 45, SRCCOPY);
17. 如何將指定的窗體,以位圖形式復(fù)制到系統(tǒng)剪切板上
void CScreenSnapDlg::toClipboard_Bio(CWnd * wnd, BOOL FullWnd)
{
CDC *dc;
if(FullWnd)
{ /* 抓取整個窗口 */
dc = new CWindowDC(wnd);
} /* 抓取整個窗口 */
else
{ /* 僅抓取客戶區(qū)時 */
dc = new CClientDC(wnd);
} /* 僅抓取客戶區(qū)時 */
CDC memDC;
memDC.CreateCompatibleDC(dc);
CBitmap bm;
CRect r;
if(FullWnd)
wnd->GetWindowRect(&r);
else
wnd->GetClientRect(&r);
CString s;
wnd->GetWindowText(s);
CSize sz(r.Width(), r.Height());
bm.CreateCompatibleBitmap(dc, sz.cx, sz.cy);
CBitmap * oldbm = memDC.SelectObject(&bm);
memDC.BitBlt(0, 0, sz.cx, sz.cy, dc, 0, 0, SRCCOPY);
//直接調(diào)用OpenClipboard(),而不用wnd->GetParent()->OpenClipboard();
wnd->OpenClipboard();
::EmptyClipboard();
::SetClipboardData(CF_BITMAP, bm.m_hObject);
CloseClipboard();
//恢復(fù)原始環(huán)境
memDC.SelectObject(oldbm);
bm.Detach();
delete dc;
}
18. 如何替換HBITMAP中的顏色值
#define COLORREF2RGB(Color) (Color & 0xff00) | ((Color >> 16) & 0xff) \
| ((Color << 16) & 0xff0000)
HBITMAP ReplaceColor (HBITMAP hBmp,COLORREF cOldColor,COLORREF cNewColor)
{
HBITMAP RetBmp=NULL;
if (hBmp)
{
HDC BufferDC=CreateCompatibleDC(NULL); // 源位圖DC
if (BufferDC)
{
SelectObject(BufferDC,hBmp); // 選入DC中
HDC DirectDC=CreateCompatibleDC(NULL); // 目標DC
if (DirectDC)
{
// 獲取源位圖大小
BITMAP bm;
GetObject(hBmp, sizeof(bm), &bm);
// 初始化BITMAPINFO信息,以便使用CreateDIBSection
BITMAPINFO RGB32BitsBITMAPINFO;
ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));
RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
RGB32BitsBITMAPINFO.bmiHeader.biWidth=bm.bmWidth;
RGB32BitsBITMAPINFO.bmiHeader.biHeight=bm.bmHeight;
RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1;
RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32;
UINT * ptPixels;
HBITMAP DirectBitmap= CreateDIBSection(DirectDC,
(BITMAPINFO *)&RGB32BitsBITMAPINFO,
DIB_RGB_COLORS,(void **)&ptPixels, NULL, 0);
if (DirectBitmap)
{
HGDIOBJ PreviousObject=SelectObject(DirectDC, DirectBitmap);
BitBlt(DirectDC,0,0,bm.bmWidth,bm.bmHeight,BufferDC,0,0,SRCCOPY);
// 轉(zhuǎn)換 COLORREF 為 RGB
cOldColor=COLORREF2RGB(cOldColor);
cNewColor=COLORREF2RGB(cNewColor);
// 替換顏色
for (int i=((bm.bmWidth*bm.bmHeight)-1);i>=0;i--)
{
if (ptPixels[i]==cOldColor) ptPixels[i]=cNewColor;
}
// 修改位圖 DirectBitmap
SelectObject(DirectDC,PreviousObject);
// 完成
RetBmp=DirectBitmap;
}
// 釋放DC
DeleteDC(DirectDC);
}
// 釋放DC
DeleteDC(BufferDC);
}
}
return RetBmp;
}
用法:
HBITMAP hBmp2 = LoadBitmap(g_hinstance,MAKEINTRESOURCE(IDB_SAMPLEBITMAP));
HBITMAP hBmp = ReplaceColor(hBmp2,0xff0000,0x00ff00); // 替換藍色為綠色
......
DeleteObject(hBmp2);
DeleteObject(hBmp);
19. 如何轉(zhuǎn)換并保存位圖
//********************************************************************************
//* 名稱:DDBToDIB
//* 作者:徐景周(jingzhou_xu@163.net)
//* 功能:設(shè)備相關(guān)轉(zhuǎn)換為設(shè)備無關(guān)位圖
//********************************************************************************
HANDLE CScreenSnapDlg::DDBToDIB( CBitmap& bitmap, DWORD dwCompression /* = BI_RGB */)
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HANDLE hDIB;
HANDLE handle;
HDC hDC;
HPALETTE hPal;
CWindowDC dc( this );
CPalette pal;
//如果支持調(diào)色板的話,則建立它
if( dc.GetDeviceCaps( RASTERCAPS ) & RC_PALETTE )
{
UINT nSize = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * 256 );
LOGPALETTE* pLP = (LOGPALETTE*)new BYTE[nSize];
pLP->palVersion = 0x300;
pLP->palNumEntries = (unsigned short)GetSystemPaletteEntries( dc, 0, 255,
pLP->palPalEntry );
pal.CreatePalette( pLP );
//釋放
delete[] pLP;
}
ASSERT( bitmap.GetSafeHandle() );
//不支持BI_BITFIELDS類型
if( dwCompression == BI_BITFIELDS )
return NULL;
//如果調(diào)色板為空,則用默認調(diào)色板
hPal = (HPALETTE) pal.GetSafeHandle();
if (hPal==NULL)
hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
//獲取位圖信息
bitmap.GetObject(sizeof(bm),(LPSTR)&bm);
//初始化位圖信息頭
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = (unsigned short)(bm.bmPlanes * bm.bmBitsPixel) ;
bi.biCompression = dwCompression;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
//計算信息頭及顏色表大小
int nColors = 0;
if(bi.biBitCount <= 8)
{
nColors = (1 << bi.biBitCount);
}
dwLen = bi.biSize + nColors * sizeof(RGBQUAD);
hDC = ::GetDC(NULL);
hPal = SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC);
//為信息頭及顏色表分配內(nèi)存
hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
if (!hDIB){
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return NULL;
}
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
*lpbi = bi;
//調(diào)用 GetDIBits 計算圖像大小
GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);
bi = *lpbi;
//圖像的每一行都對齊(32bit)邊界
if (bi.biSizeImage == 0){
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;
if (dwCompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}
//重新分配內(nèi)存大小,以便放下所有數(shù)據(jù)
dwLen += bi.biSizeImage;
handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE) ;
if (handle != NULL)
hDIB = handle;
else
{
GlobalFree(hDIB);
//重選原始調(diào)色板
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return NULL;
}
//獲取位圖數(shù)據(jù)
lpbi = (LPBITMAPINFOHEADER)hDIB;
//最終獲得的DIB
BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
0L, //掃描行起始處
(DWORD)bi.biHeight, //掃描行數(shù)
(LPBYTE)lpbi //位圖數(shù)據(jù)地址
+ (bi.biSize + nColors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, //位圖信息地址
(DWORD)DIB_RGB_COLORS); //顏色板使用RGB
if( !bGotBits )
{
GlobalFree(hDIB);
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return NULL;
}
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return hDIB;
}
//********************************************************************************
//* 名稱:SaveBitmapToFile
//* 修改:徐景周(jingzhou_xu@163.net)
//* 功能:保存為位圖文件
//********************************************************************************
BOOL CScreenSnapDlg::SaveBitmapToFile(HBITMAP hBitmap , CString lpFileName)
{
HDC hDC; //設(shè)備描述表
int iBits; //當前顯示分辨率下每個像素所占字節(jié)數(shù)
WORD wBitCount; //位圖中每個像素所占字節(jié)數(shù)
DWORD dwPaletteSize=0, //定義調(diào)色板大小, 位圖中像素字節(jié)大小 ,位圖文件大小 , 寫入文件字節(jié)數(shù)
dwBmBitsSize,
dwDIBSize, dwWritten;
BITMAP Bitmap;
BITMAPFILEHEADER bmfHdr; //位圖屬性結(jié)構(gòu)
BITMAPINFOHEADER bi; //位圖文件頭結(jié)構(gòu)
LPBITMAPINFOHEADER lpbi; //位圖信息頭結(jié)構(gòu)
HANDLE fh, hDib, hPal,hOldPal=NULL; //指向位圖信息頭結(jié)構(gòu),定義文件,分配內(nèi)存句柄,調(diào)色板句柄
//計算位圖文件每個像素所占字節(jié)數(shù)
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits <= 1)
wBitCount = 1;
else if (iBits <= 4)
wBitCount = 4;
else if (iBits <= 8)
wBitCount = 8;
else if (iBits <= 24)
wBitCount = 24;
//計算調(diào)色板大小
if (wBitCount <= 8)
dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);
//設(shè)置位圖信息頭結(jié)構(gòu)
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
dwBmBitsSize = ((Bitmap.bmWidth *
wBitCount+31)/32)* 4
*Bitmap.bmHeight ;
//為位圖內(nèi)容分配內(nèi)存
hDib = GlobalAlloc(GHND,dwBmBitsSize+
dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
// 處理調(diào)色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = ::GetDC(NULL);
hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
RealizePalette(hDC);
}
// 獲取該調(diào)色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
//恢復(fù)調(diào)色板
if (hOldPal)
{
SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
RealizePalette(hDC);
::ReleaseDC(NULL, hDC);
}
//創(chuàng)建位圖文件
fh = CreateFile(lpFileName, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
// 設(shè)置位圖文件頭
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)
+ (DWORD)sizeof(BITMAPINFOHEADER)
+ dwPaletteSize;
// 寫入位圖文件頭
WriteFile(fh, (LPSTR)&bmfHdr, sizeof
(BITMAPFILEHEADER), &dwWritten, NULL);
// 寫入位圖文件其余內(nèi)容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize,
&dwWritten, NULL);
//消除內(nèi)存分配
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
return TRUE;
}
20. 如何獲取局域網(wǎng)上計算機名及它們的IP地址
l 連接ws2_32.lib和 mpr.lib庫
l #include winsock2.h
CString strTemp;
struct hostent *host;
struct in_addr *ptr; // 檢索IP地址
DWORD dwScope = RESOURCE_CONTEXT;
NETRESOURCE *NetResource = NULL;
HANDLE hEnum;
WNetOpenEnum( dwScope, NULL, NULL,
NULL, &hEnum );
WSADATA wsaData;
WSAStartup(MAKEWORD(1,1),&wsaData);
if ( hEnum )
{
DWORD Count = 0xFFFFFFFF;
DWORD BufferSize = 2048;
LPVOID Buffer = new char[2048];
WNetEnumResource( hEnum, &Count,
Buffer, &BufferSize );
NetResource = (NETRESOURCE*)Buffer;
char szHostName[200];
unsigned int i;
for ( i = 0;
i < BufferSize/sizeof(NETRESOURCE);
i++, NetResource++ )
{
if ( NetResource->dwUsage ==
RESOURCEUSAGE_CONTAINER &&
NetResource->dwType ==
RESOURCETYPE_ANY )
{
if ( NetResource->lpRemoteName )
{
CString strFullName =
NetResource->lpRemoteName;
if ( 0 ==
strFullName.Left(2).Compare("\\\\") )
strFullName =
strFullName.Right(
strFullName.GetLength()-2);
gethostname( szHostName,
strlen( szHostName ) );
host = gethostbyname(strFullName);
if(host == NULL) continue;
ptr = (struct in_addr *)
host->h_addr_list[0];
// =. 分隔開IP:211.40.35.76.
int a = ptr->S_un.S_un_b.s_b1; // 211
int b = ptr->S_un.S_un_b.s_b2; // 40
int c = ptr->S_un.S_un_b.s_b3; // 35
int d = ptr->S_un.S_un_b.s_b4; // 76
strTemp.Format("%s --> %d.%d.%d.%d",
strFullName,a,b,c,d);
AfxMessageBox(strTemp);
}
}
}
delete Buffer;
WNetCloseEnum( hEnum );
}
WSACleanup();
