//这个帖子是如此的经典以至于被我贴遍大江南北长城内外。现在继续贴
??
??徐景周
??未来工作室(Future Studio)
??
??1. 如何激活当前屏幕保护程序
??// 激活当前屏幕保护程序, jingzhou xu
?? PostMessage(WM_SYSCOMMAND,SC_SCREENSAVE,0);
??
??2. 如何禁止/启用屏幕保护及电源管理
??static UINT dss_GetList[] = {SPI_GETLOWPOWERTIMEOUT, SPI_GETPOWEROFFTIMEOUT, S
??PI_GETSCREENSAVETIMEOUT};
??
??static UINT dss_SetList[] = {SPI_SETLOWPOWERTIMEOUT, SPI_SETPOWEROFFTIMEOUT, S
??PI_SETSCREENSAVETIMEOUT};
??
??static const int dss_ListCount = _countof(dss_GetList);
??l 禁止屏幕保护及电源管理
??{
??m_pValue = new int[dss_ListCount];
??for (int x=0;x
??{
??// 禁止屏幕保护及电源管理
??VERIFY(SystemParametersInfo (dss_SetList[x], 0, NULL, 0));
??}
??delete[] m_pValue;
??}
??
??l 启用屏幕保护及电源管理
??{
??m_pValue = new int[dss_ListCount];
??for (int x=0;x??{
??//启用屏幕保护及电源管理
??VERIFY(SystemParametersInfo (dss_SetList[x], m_pValue[x], NULL, 0));
??}
??delete[] m_pValue;
??}
??
??3. 如何激活和关闭IE浏览器
??//激活并打开IE
??void lounchIE()
??{
?? HWND h=FindWindowEx(NULL,NULL,NULL,
?? "Microsoft Internet Explorer") ;
?? ShellExecute(h,"open","C:\simple.html",
?? NULL,NULL,SW_SHOWNORMAL);
??
??}
??
??//关闭IE及其它应用
??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 最后加入呼应涵数处理:
??void CCreateTreeDlg::OnGetInfoTip(NMHDR* pNMHDR,
?? LRESULT* pResult)
?? {
?? *pResult = 0;
?? NMTVGETINFOTIP* pTVTipInfo = (NMTVGETINFOTIP*)pNMHDR;
?? LPARAM itemData = (DWORD) pTVTipInfo->lParam;
?? //对应每个条目的数据
?? HTREEITEM hItem = pTVTipInfo->hItem;
?? CString tip;
?? HTREEITEM hRootItem = m_chassisTree.GetRootItem();
?? if (hRootItem != pTVTipInfo->hItem)
?? {
?? tip = "树结点的提示";
?? }
?? else
?? {
?? tip = "树根上的提示";
?? }
?? strcpy(pTVTipInfo->pszText, (LPCTSTR) tip);
??}
??
??5. 如何获取系统信息框的路径
??#include
??
??#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, &d
??wSize );
?? #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_REA
??D );
??
?? if ( nRet == ERROR_SUCCESS )
?? {
?? #if ( _MFC_VER >= 0x0700 )
?? reg.QueryStringValue( IDS_REG_VAL_MSINFO_PATH2, pszPath, &dwSi
??ze );
?? #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;
?? //获取应用实例
?? 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_SHOWNORM
??AL);> //运行它.
?? return 1;
??}
??
??7. 如何遍历整个目录
??#include
??#include
??
??//浏览目录.
??void BrowseFolder( void )
??{
?? TCHAR path[MAX_PATH];
?? BROWSEINFO bi = { 0 };
?? bi.lpszTitle = ("递归调用所有目录");
?? LPITEMIDLIST pidl = SHBrowseForFolder ( &bi );
??
?? if ( pidl != 0 )
?? {
?? // 获取目录路径
?? SHGetPathFromIDList ( pidl, path );
??
?? //设置为当前路径
?? SetCurrentDirectory ( path );
??
?? //搜索所有子目录
?? SearchFolder( path );
??
??
?? // 释放内存
?? 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 ];
??
?? //复制初始用户选择目录
?? strcpy( pathbak, path );
??
?? //寻找第一个文件
?? hFind = FindFirstFile ( "*.*", &FindFileData );
??
?? //搜索所有文件及子目录
?? do
?? {
?? if ( hFind != INVALID_HANDLE_VALUE )
?? {
?? //如果是当前目录或父目录,跳过
?? if ( ! ( strcmp( FindFileData.cFileName, "." ) ) || ! ( strcmp
??( FindFileData.cFileName, ".." ) ) )
?? {
?? continue;
?? }
??
?? //恢复初始用户选择目录
?? strcpy( path, pathbak );
??
?? //列出所有发现的文件
?? sprintf( path, "%s\%s", path, FindFileData.cFileName );
??
?? //如果 SetCurrentDirectory 成功的话,则它是一个目录,递归调用继
??续搜索子目录
?? 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_HAND
??LE_VALUE );
??
?? FindClose ( hFind );
??}
??
??8. 如何禁止/启用系统热键
??bool bOld;
??l 禁止系统热键
??//屏蔽掉系统键
??SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,true,&bOld,SPIF_UPDATEINIFILE);
??
??
??l 启用系统热键
??//恢复系统热键
??SystemParametersInfo(SPI_SETSCREENSAVERRUNNING,false,&bOld,SPIF_UPDATEINIFILE)
??;
??
??9. 如何隐藏/显示WINDOWS系统任务栏
??l 隐藏系统任务栏
??//隐藏WINDOWS系统任务栏
?? ::ShowWindow (::FindWindow("Shell_TrayWnd",NULL),SW_HIDE);
??l 显示系统任务栏
??//恢复WINDOWS系统任务栏正常显示
??::ShowWindow (::FindWindow("Shell_TrayWnd",NULL),SW_SHOW);
??
??10. 如何实现窗口到系统区图标间的动画效果
??//****************************************************************************
??****
??//* 名称:FindTrayWnd
??//* 作者:徐景周(jingzhou_xu@163.net)
??//* 功能:在显示窗体动画效果前,先寻找系统区位置
??//****************************************************************************
??****
?? 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;
?? }
??
?? // 当找到时钟窗口时表示可以结束了
?? 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)
??//* 功能:显示窗口动画效果的涵数
??//****************************************************************************
??****
??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 为托盘区矩形
?? CRect rcWnd;
?? GetWindowRect(rcWnd);
?? if(ShowFlag) //窗体滑向系统区
?? DrawAnimatedRects(GetSafeHwnd(),IDANI_CAPTION,rcWnd,rect);
?? else //窗体从系统区滑出
?? DrawAnimatedRects(GetSafeHwnd(),IDANI_CAPTION,rect,rcWnd);
?? }
??}
??
??用法如下:
??if(IsWindowVisible()) //窗体是否已隐藏
??{
?? ShowWindow(SW_HIDE); //先隐藏窗体
?? WinAnimation(true); //窗体动画滑入到系统区中
??}
??else
??{
??WinAnimation(false); //窗体动画从系统区滑出
?? ShowWindow(SW_SHOW);
??}
??
??11. 如何判断当前操作系统的版本
??//----------------------------------------------------------------------------
??--------------------
??//判断操作系统涵数及变量,jingzhou xu
??typedef enum tagWin32SysType{
?? Windows32s,
?? WindowsNT3,
?? Windows95,
?? Windows98,
?? WindowsME,
?? WindowsNT4,
?? Windows2000,
?? WindowsXP
??}Win32SysType;
??
??//判断操作系统涵数及变量,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)ShellTy
??pe=Windows2000;
?? else if(osvi->dwMajorVersion==5L&&osvi->dwMinorVersion==1L)ShellTy
??pe=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=W
??indows98;
?? else if(osvi->dwMajorVersion==4L&&osvi->dwMinorVersion==90L)ShellT
??ype=WindowsME;
?? free(osvi);
?? }
?? }
??
?? return ShellType;
??}
??//----------------------------------------------------------------------------
??--------------------
??
??12. 如何在指定矩形框内水平/垂直显示多行文字
??///////////////////////////////////////////////////////
??//说明:
??// 在矩形框中水平或垂直显示多行文字,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, l
??ong 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;
?? }
??
?? //------------------------------------------------------------------------
??---------------------
?? //功能:根据新、老矩形,重新计算行数,使文字多行显示,jingzhou xu
?? //------------------------------------------------------------------------
??---------------------
?? //一行中最大字符数
?? int nMaxLineChar = abs(lpRect->right - lpRect->left) / tmpWidth ;
??
?? //记录当前行的宽度
?? short theLineLength=0;
?? //记录当前行中汉字字节数,以防止将一半汉字分为两行
?? unsigned short halfChinese=0;
??
?? for(int i=0; i<=szString.GetLength()-1; i++)
?? {
?? if(((unsigned char)szString.GetAt(i) == 0x0d) && ((unsigned char)szStr
??ing.GetAt(i+1) == 0x0a))
?? theLineLength=0;
??
?? //大于0xa1的字节为汉字字节
?? 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. 如何在指定矩形中旋转显示文字
??///////////////////////////////////////////////////////
??//说明:
??// 在矩形框中旋转方式显示文字,jingzhou xu
??//参数:
??// pDC: DC指针
??// str: 显示文字
??// rect: 显示范围
??// angle: 旋转角度
??// nOptions: ExtTextOut()中相应设置
??///////////////////////////////////////////////////////
??void DrawRotatedText(CDC* pDC, const CString str, CRect rect,
?? double angle, UINT nOptions)
??{
?? //按比例转换角度值
?? 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像素图标转换为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. 如何按指定角度旋转显示内存位图(用法和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);
??
?? //判断出图像可以沿任意方向旋转的矩形框
?? if(width>height)height = width;
?? else
?? width = height;
??
??
?? HDC memDC = CreateCompatibleDC(destDC);
?? HBITMAP memBmp = CreateCompatibleBitmap(destDC, width, height);
??
?? HBITMAP obmp = (HBITMAP) SelectObject(memDC, memBmp);
??
?? //内存DC新在中心点
?? int newCentre = int(float(width)/2);
??
?? //开始旋转
?? 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);
?? }
??
?? //复制到目标DC上
?? BitBlt(destDC, destx1, desty1, width, height, memDC, 0,0,mode);
??
??
?? //释放内存
?? SelectObject(memDC, obmp);
??
?? DeleteDC(memDC);
?? DeleteObject(memBmp);
??}
??
??用法:
??RotBlt(dc, 0,0,150,150,memDC,200,0, 45, SRCCOPY);
??
??17. 如何将指定的窗体,以位图形式复制到系统剪切板上
??void CScreenSnapDlg::toClipboard_Bio(CWnd * wnd, BOOL FullWnd)
??{
?? CDC *dc;
?? if(FullWnd)
?? { /* 抓取整个窗口 */
?? dc = new CWindowDC(wnd);
?? } /* 抓取整个窗口 */
?? else
?? { /* 仅抓取客户区时 */
?? dc = new CClientDC(wnd);
?? } /* 仅抓取客户区时 */
??
?? 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);
??
?? //直接调用OpenClipboard(),而不用wnd->GetParent()->OpenClipboard();
?? wnd->OpenClipboard();
??
?? ::EmptyClipboard();
?? ::SetClipboardData(CF_BITMAP, bm.m_hObject);
?? CloseClipboard();
??
?? //恢复原始环境
?? 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 *)&RGB32BitsBITMAPIN
??FO,
?? DIB_RGB_COLORS,(void **)&ptPixel
??s, NULL, 0);
?? if (DirectBitmap)
?? {
?? HGDIOBJ PreviousObject=SelectObject(DirectDC, DirectBitmap
??);
?? BitBlt(DirectDC,0,0,bm.bmWidth,bm.bmHeight,BufferDC,0,0,SR
??CCOPY);
??
?? // 转换 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. 如何转换并保存位图
??//****************************************************************************
??****
??//* 名称:DDBToDIB
??//* 作者:徐景周(jingzhou_xu@163.net)
??//* 功能:设备相关转换为设备无关位图
??//****************************************************************************
??****
??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;
?? //如果支持调色板的话,则建立它
?? if( dc.GetDeviceCaps( RASTERCAPS ) & RC_PALETTE )
?? {
?? UINT nSize = sizeof(LOGPALETTE) + ( sizeof(PALETTEENTRY) * 25
??6 );
?? LOGPALETTE* pLP = (LOGPALETTE*)new BYTE[nSize];
?? pLP->palVersion = 0x300;
?? pLP->palNumEntries = (unsigned short)GetSystemPaletteEntries( dc, 0, 2
??55,
?? pLP->palPalEntry );
??
?? pal.CreatePalette( pLP );
??
?? //释放
?? delete[] pLP;
?? }
??
?? ASSERT( bitmap.GetSafeHandle() );
??
?? //不支持BI_BITFIELDS类型
?? if( dwCompression == BI_BITFIELDS )
?? return NULL;
??
?? //如果调色板为空,则用默认调色板
?? 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);
??
?? //为信息头及颜色表分配内存
?? hDIB = GlobalAlloc(GMEM_FIXED,dwLen);
??
?? if (!hDIB){
?? SelectPalette(hDC,hPal,FALSE);
?? ::ReleaseDC(NULL,hDC);
?? return NULL;
?? }
??
?? lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
??
?? *lpbi = bi;
??
?? //调用 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;
?? }
??
?? //重新分配内存大小,以便放下所有数据
?? dwLen += bi.biSizeImage;
?? handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE) ;
?? if (handle != NULL)
?? hDIB = handle;
?? else
?? {
?? GlobalFree(hDIB);
??
?? //重选原始调色板
?? SelectPalette(hDC,hPal,FALSE);
?? ::ReleaseDC(NULL,hDC);
?? return NULL;
?? }
??
?? //获取位图数据
?? lpbi = (LPBITMAPINFOHEADER)hDIB;
??
?? //最终获得的DIB
?? BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
?? 0L, //扫描行起始处
?? (DWORD)bi.biHeight, //扫描行数
?? (LPBYTE)lpbi //位图数据地址
?? + (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; //设备描述表
?? int iBits; //当前显示分辨率下每个
??像素所占字节数
?? WORD wBitCount; //位图中每个像素所占字节
??数
?? DWORD dwPaletteSize=0, //定义调色板大小, 位图中像
??素字节大小 ,位图文件大小 , 写入文件字节数
?? dwBmBitsSize,
?? dwDIBSize, dwWritten;
?? BITMAP Bitmap;
?? BITMAPFILEHEADER bmfHdr; //位图属性结构
?? BITMAPINFOHEADER bi; //位图文件头结构
??
?? LPBITMAPINFOHEADER lpbi; //位图信息头结构
?? HANDLE fh, hDib, hPal,hOldPal=NULL; //指向位图信息头结构,定义文
??件,分配内存句柄,调色板句柄
??
?? //计算位图文件每个像素所占字节数
?? 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;
?? //计算调色板大小
?? if (wBitCount <= 8)
?? dwPaletteSize = (1 << wBitCount) *sizeof(RGBQUAD);
??
?? //设置位图信息头结构
?? 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 ;
??
?? //为位图内容分配内存
?? hDib = GlobalAlloc(GHND,dwBmBitsSize+
?? dwPaletteSize+sizeof(BITMAPINFOHEADER));
?? lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
?? *lpbi = bi;
??
?? // 处理调色板
?? hPal = GetStockObject(DEFAULT_PALETTE);
?? if (hPal)
?? {
?? hDC = ::GetDC(NULL);
?? hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
?? RealizePalette(hDC);
?? }
??
?? // 获取该调色板下新的像素值
?? GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
?? (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize,
?? (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
??
?? //恢复调色板
?? if (hOldPal)
?? {
?? SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
?? RealizePalette(hDC);
?? ::ReleaseDC(NULL, hDC);
?? }
??
?? //创建位图文件
?? fh = CreateFile(lpFileName, GENERIC_WRITE,
?? 0, NULL, CREATE_ALWAYS,
?? FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
??
?? if (fh == INVALID_HANDLE_VALUE)
?? return FALSE;
??
?? // 设置位图文件头
?? bmfHdr.bfType = 0x4D42; // "BM"
?? dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPale
??tteSize + 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);
?? // 写入位图文件其余内容
?? WriteFile(fh, (LPSTR)lpbi, dwDIBSize,
?? &dwWritten, NULL);
??
?? //消除内存分配
?? GlobalUnlock(hDib);
?? GlobalFree(hDib);
?? CloseHandle(fh);
??
?? return TRUE;
??}
??
??20. 如何获取局域网上计算机名及它们的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();
??
??
??--
阅读(1197) | 评论(0) | 转发(0) |