日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

VC++ 常用编程技巧总结

發布時間:2025/4/14 c/c++ 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 VC++ 常用编程技巧总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

VC++6.0的使用以及編程技巧整理



1、MDI子窗口一啟動就最大化 ??
? BOOL ? CChildFrame::PreCreateWindow(CREATESTRUCT& ? cs) ?
? { ?
? // ? TODO: ? Modify ? the ? Window ? class ? or ? styles ? here ? by ? modifying ?
? // ? ? the ? CREATESTRUCT ? cs ?
? cs.style=WS_CHILD ? | ? WS_VISIBLE ? | ? WS_OVERLAPPEDWINDOW|WS_MAXIMIZE; ?
? if( ? !CMDIChildWnd::PreCreateWindow(cs) ? ) ?
? return ? FALSE; ?
? ?
? return ? TRUE; ?
? } ? ?
?
2、主窗口最大化: ?
? ? ? ? ? 在 ? InitStance ? 函數中設定 ? m_nCmdShow的取值. ??
? ? ? ? ? ?m_nCmdShow ? = ? SW_SHOWMAXIMIZED; ? ?
? ? if ? (!ProcessShellCommand(cmdInfo)) ?
? ? ? return ? FALSE; ??


? MDI窗口: ?
? ? ? ? ? 重載 ? MDI ? Window ? 的PreCreateWindow函 ?
? 數,設置WS_MAXIMIZE ?
? 文檔一生成就最大化: ?
? ? ? ? ? 在視類重載的OnInitUpdate成員函數中加上: ? ?
? ? ? ? ? CMDIChildWnd ? *pWnd=(CMDIChildWnd ? *)GetParentFrame(); ? ?
? ? ? ? ? pWnd->MDIMaximize();
?3、設置多文檔的標題
設置標題在如下兩個函數
BOOL CTOLLGATE_OF_CITYDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
SetTitle ("你的文檔名");
return TRUE;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
m_strTitle ="標題";
return TRUE;
}
?4 mdi怎樣可以使啟動程序時不打開子窗口?
在應用程序的初始化函數InitInstance中的 ?
? CcommandLineInfo ? cmdInfo; ?
? 語句后加入: ?
? cmdInfo.m_nShellCommand=CCommandLineInfo::FileNothing; ? ? (要尤氳拇耄??
? ?
? ParseCommandLine(cmdInfo); ? ? (該句已有,不用加) ?
? 即可。 ?
? 是CWinApp類中的函數
5 怎樣單擊窗體任何位置就可移動窗體
加上左鍵按下消息 ?
? void ? CXXXDlg::OnLButtonDown(UINT ? nFlags, ? CPoint ? point) ? ?
? { ??
? ? //加上下面這句話 ?
? PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y)); ? ??
? CDialog::OnLButtonDown(nFlags, ? point); ??
??
? } ?
6 VC下用ADO連接ORACLE數據庫
Oracle公司提供的連接方式: ?
? 使用標準安全級別: ?
? strConnect ? = ? _T("Provider=OraOLEDB.Oracle;Data ? Source=MyOracleDB;User ? Id=myUsername;Password=myPassword;"); ?
? 使用信任連接 ?
? 1.strConnect ? = ? _T("Provider=OraOLEDB.Oracle;Data ? Source=MyOracleDB;User ? Id=/;Password=;"); ? UID為'/' ?
? 2.strConnect ? = ? _T("Provider=OraOLEDB.Oracle;Data ? Source=MyOracleDB;OSAuthent=1;");使用OSAuthent=1 ?
? 對于連接字符串可以參考以下網頁: ? http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdreforacleprovspec.asp?frame=true ?
? http://download-west.oracle.com/otndoc/oracle9i/901_doc/win.901/a90171/using.htm ?
? ===>ODBC ? 配置數據源 ?
? strConnect ? = ? _T("DSN=ADOTest");
?
編程小技巧
http://hi.baidu.com/original/blog/item/c0f7e850e9b6545f1138c275.html
?
去掉單文檔的“無標題”
? if( !CFrameWnd::PreCreateWindow(cs) )
? return FALSE;
?// TODO: Modify the Window class or styles here by modifying
?// ?the CREATESTRUCT cs
?cs.style ? &= ? ~FWS_ADDTOTITLE;
?VC編程做個超級鏈接的文本按鈕
http://sjtu.blog.sohu.com/71163647.html
VC下利用ADO連接Access數據庫?
http://blog.csdn.net/pixy0m0/archive/2007/04/17/1568224.aspx
SQL語句VC中的分行?
pcmd->CommandText ? = ? "SELECT ? * ? ? ? ? ? ? ? \ ?
? FROM ? OrderTable ? WHERE ? OrderID ? = ? ?";
各種類型轉換


常用數據類型使用轉換詳解
http://sjtu.blog.sohu.com/77555070.html
CString 轉 int ?atoi
CString to double
Cstring與double char 的轉換
http://blog.csdn.net/paobo/archive/2007/05/15/1610032.aspx
四舍五入 ?int(num+0.5) ? %.2f
查詢Excel表要用$結尾不然找不到 ?select * ?FROM [Stockpool$]
數據庫表中字段含有括號的話 用中括號括起來表示特殊字符 例如 [EPS(T+1)]
CListCtrl使用技巧 ? ?http://sjtu.blog.sohu.com/72301523.html
打開網頁文件
ShellExecute(hWnd,"open","ieexplorer",CString("file://")+filename ? + ? CString("#a1"), ? NULL,SW_SHOWNORMAL); ??
深入淺出ShellExecute
http://sjtu.blog.sohu.com/72316353.html
?Excel中時間字段的查詢: Time>#2007-12-03 00:00:00#
?VC窗口自由的調整大小的實現
http://www.codeproject.com/dialog/easysize.asp
http://www.xfbbs.com/ArticleShow/85/Article_Show_72223.html
?
用VC++獲取系統時間幾種方法?
CTime:
%Y%m%d%h%M%S 年月日 時分秒
就用CTime::GetDayOfWeek() ? or ? COleDateTime::::GetDayOfWeek()啊,他返回一個int,如果返回值是1就說明是星期天,如果是2表示星期一...如果是7表示星期六(每個星期的第一天是星期天)?
A:
1 使用time_t time( time_t * timer ) ? ?精確到秒
  計算時間差使用double difftime( time_t timer1, time_t timer0 )
2 使用clock_t clock() 得到的是CPU時間 ? ?精確到1/CLOCKS_PER_SEC秒
3 使用DWORD GetTickCount() 得到的是系統運行的時間 精確到毫秒
4 如果使用MFC的CTime類,可以用CTime::GetCurrentTime() 精確到秒
5 要獲取高精度時間,可以使用
? ? BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency)獲取系統的計數器的頻率
? ? BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount)獲取計數器的值
? ? 然后用兩次計數器的差除以Frequency就得到時間。
6 還有David的文章中提到的方法:
? ? Multimedia Timer Functions
? ? The following functions are used with multimedia timers.
? ? timeBeginPeriod/timeEndPeriod/timeGetDevCaps/timeGetSystemTime
? ? timeGetTime/timeKillEvent/TimeProc/timeSetEvent ?精度很高?
Q:GetTickCount()函數,說是毫秒記數,是真的嗎,還是精確到55毫秒?
A:
GetTickCount()和GetCurrentTime()都只精確到55ms(1個tick就是55ms)。如果要精確到毫秒,應該使用timeGetTime函數或QueryPerformanceCounter函數。具體例子可以參考QA001022 "VC++中使用高精度定時器"、QA001813 "如何在Windows實現準確的定時"和QA004842 "timeGetTime函數延時不準"。
Q:vc++怎樣獲取系統時間,返回值是什么類型的變量呢??
GetSystemTime返回的是格林威志標準時間
GetLocalTime,和上面用法一樣,返回的是你所在地區的時間,中國返回的是北京時間
?
VOID GetSystemTime(
LPSYSTEMTIME lpSystemTime // address of system time structure
);
函數就可以獲得了,其中LPSYSTEMTIME 是個結構體
含:年,月,日,周幾,小時,分,秒,毫秒。
?
Disable一個控件:GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
?
VC中如何發布Release版本 工具欄上點右鍵,選擇編譯,將編譯win32debug改為win32 Release即可。如果需要調試的話,還需要再改回來方可
?
VC程序可以再其它機子上運行:
你的目標程序需要動態鏈接庫文件的支持, ? ?
? 把程序中用到的DLL文件放到程序的目錄下就可以運行了。
project->setting->General->下拉框中選擇"Use ? MFC ? in ? a ? Static ? Library”
?
?
第一:private, public, protected 訪問標號的訪問范圍。
private:只能由1.該類中的函數、2.其友元函數訪問。
不能被任何其他訪問,該類的對象也不能訪問。


protected:可以被1.該類中的函數、2.子類的函數、以及3.其友元函數訪問。
但不能被該類的對象訪問。


public:可以被1.該類中的函數、2.子類的函數、3.其友元函數訪問,也可以由4.該類的對象訪問。
?
注:友元函數包括3種:設為友元的普通的非成員函數;設為友元的其他類的成員函數;設為友元類中的所有成員函數。


第二:類的繼承后方法屬性變化。
private 屬性不能夠被繼承。
使用private繼承,父類的protected和public屬性在子類中變為private;
使用protected繼承,父類的protected和public屬性在子類中變為protected;
使用public繼承,父類中的protected和public屬性不發生改變;?
?
如下所示:?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?public: ? ? ? ? ? ?protected: ? ? ? private:
public繼承 ? ? ? ? ? ? public ? ? ? ? ? ? protected ? ? ? ?不可用?
protected繼承 ? ? ? protected ? ? ? protected ? ? ? ?不可用?
private繼承 ? ? ? ? ? ?private ? ? ? ? ? private ? ? ? ? ? ? 不可用?


protected繼承和private繼承能降低訪問權限。
?
?CTime COleDateTime的常用操作和比較
百分號的表示
用%%表示% ,或者CStrng ? str; ?
? str.format("select ? * ? from ? Name ? where ? address ? like ? %sabc%s","%","%");
viewform.cpp line 69 錯誤: 應該把dialog改為child。
?
取消所有斷點 edit->breakpoints->remove all 或者 Ctrl+Shift+F9
?
設置checkBox屬性為選中 ?((CButton ? *)GetDlgItem(IDC_CHECK1+i))->SetCheck(1); ?
判斷是否選中  if(IsDlgButtonChecked(IDC_SEX1)) 
取得活動視圖和主框架
? CMainFrame ? *pMainFrame=(CMainFrame ? *)AfxGetMainWnd(); ?
? CSRSFormView ? * pView ?=(CSRSFormView *)pMainFrame->GetActiveView();
關于missing ';' before identifier 'A' ?兩個文件的相互引用引起的...
?
VC中看不到類:刪除clw文件 重新建立
?
獲取控件的中心:GetDlgItem(IDC_SEARCH1)->GetWindowRect(&rc); rc.CenterPoint()
?
SendMessage 傳遞多個變量:
? ? ? ? tObj *fi=new tObj;
? ? ? ? fi->iItem=idx;
? ? ? ? fi->iFolder=iSelFolder;
? ?GetOwner()->SendMessage(WM_OUTBAR_NOTIFY, NM_OB_ITEMCLICK, (UINT)fi);
那邊接收到后再用(tObj*)轉換回來
?
問題: 請問何時用UpdateData(false),何時用UpdateData(true)呢?
答案:當你使用了ClassWizard建立了控件和變量之間的聯系后:當你修改了變量的值,而希望對話框控件更新顯示,就應該在修改變量后調用UpdateData(FALSE);如果你希望知道用戶在對話框中到底輸入了什么,就應該在訪問變量前調用UpdateData(TRUE)。
設置控件標題 ? GetDlgItem(IDC_GetCapProfit)->SetWindowText("全部顯示");
?
DateTime change事件被執行二次的改進:
?static ? BOOL ? bOK=TRUE; ?
#if ? 1//判斷是否有CMonthCalCtrl,若有會發送兩次Change,截第二次即可 ?
?CDateTimeCtrl* ? pCtrl ? = ? (CDateTimeCtrl*) ? GetDlgItem(IDC_DATESELECTED); ?
?ASSERT(pCtrl ? != ? NULL); ?
?CMonthCalCtrl* ? pMoCalCtrl ? = ? pCtrl->GetMonthCalCtrl(); ?
?if(pMoCalCtrl ? != ? NULL) ?
? ? ? ? bOK ? = ? !bOK; ?
#endif ?
?if(bOK) ?
? AfxMessageBox(""); ?
? *pResult ? = ? 0; ? ?
無模式對話框:Cdlg dlg; dlg.Create(IDD_DIALOG1,this); dlg.ShowWindow(SW_SHOW);
先為對話框加上2個radio button,分別是Radio1和Radio2。
問題1:如何讓Radio1或者Radio2默認選上?如何知道哪個被選上了?


關鍵是選上,“默認”只要放在OnInitDialog()即可。三種方法可以讓它選上,
第一種:
((CButton *)GetDlgItem(IDC_RADIO1))->SetCheck(TRUE);//選上
((CButton *)GetDlgItem(IDC_RADIO1))->SetCheck(FALSE);//不選上
((CButton *)GetDlgItem(IDC_RADIO1))->GetCheck();返回1表示選上,0表示沒選上
第二種:
關聯一個congtrol型變量(子類化),好ctrl+W(即打開classwizard),點開 Member Variables,咦?怎么沒有IDC_RADIO1這個ID?原來是沒有分組。因為radio button通常都是成組使用的,在一組里面是互斥的。取消,回到對話框資源面板,右鍵Radio1查看屬性把Group選上,那么,Radio1和Radio2就是一組了(怎么知道他們是一組的?后面說)。此時,就可以為Radio1增加一congtrol型變量m_ctrlRadio1了。如下:
m_ctrlRadio1.SetCheck(TRUE);
同樣可以使用GetCheck()獲取狀態。
第三種:
關聯一個int型變量(同樣需要先分組)m_nRadio1,打開對話框構造函數,你會發現有:
m_nRadio1 = -1;m_nRadio1別賦值-1表示哪個都沒有選上。如果你把-1改成0,就會發現Radio1默認被選上了,依此類推,m_nRadio1的值為1就是第二個被選上了(這里同樣有問題,哪個是第一個?哪個是第二個?)。獲取狀態很簡單,UpdateData(TRUE)后判斷m_nRadio1的值即可。
問題2:如何使用多組?


多組和一組是一樣的使用,只要搞清楚哪個是哪一組的就行了。再為對話框添加Radio3和Radio4。很簡單,先為這些Radio Button排個順序,就是排列他們的TAB ORDER。在對話框資源面板上Ctrl+D,然后按你自己的理想順序用鼠標逐個點擊就可以了。不妨假設Radio1、Radio2、Radio3、Radio4分別是1、2、3、4。Radio1和Radio3都選上Group屬性,那么,1、2是一組,3、4是另外一組,因為分組的原則是在選上Group屬性的這一個開始直到碰到下一個選上Group屬性的。你不妨再Ctrl+D,令Radio1、Radio2、Radio3、Radio4分別是1、3、2、4,那么Radio1和Radio3是一組,如果m_nRadio1=1,此時是Radio3被選上而不是Radio2被選上。分好了組就分別使用它們吧。
嗯,也許你還要為它們添加鼠標單擊事件,非常簡單。
?
一、對單“磁ソ蟹腫椋
每組的第一個單“磁ド柚檬糶裕篏roup,Tabstop,Auto;其余按鈕設置屬性Tabstop,Auto。如:
Radio1、Radio2、Radio3為一組,Radio4、Radio5為一組
設定Radio1屬性:Group,Tabstop,Auto
設定Radio2屬性:Tabstop,Auto
設定Radio3屬性:Tabstop,Auto
設定Radio4屬性:Group,Tabstop,Auto
設定Radio5屬性:Tabstop,Auto
二、用ClassWizard為單選控件定義變量,每組只能定義一個。如:m_Radio1、m_Radio4。
三、用ClassWizard生成各單“磁サ牡セ饗⒑⒓尤肽諶藎
void CWEditView::OnRadio1()
{
? ? m_Radio1 = 0; ? ?//第一個單“磁ケ謊≈
}
void CWEditView::OnRadio2()
{
? ? m_Radio1 = 1; ? ?//第二個單“磁ケ謊≈
}
void CWEditView::OnRadio3()
{
? ? m_Radio1 = 2; ? ?//第三個單“磁ケ謊≈
}
void CWEditView::OnRadio4()
{
? ? m_Radio4 = 0; ? ?//第四個單“磁ケ謊≈
}
void CWEditView::OnRadio5()
{
? ? m_Radio4 = 1; ? ?//第五個單“磁ケ謊≈
}
四、設置默認按鈕:
在定義控件變量時,ClassWizard在構造函數中會把變量初值設為-1,只需把它改為其它值即可。
如:
?//{{AFX_DATA_INIT(CUnitBlockTypeFlankPublicAdd)
?m_Radio1 = 0; ? ?//初始時第一個單“磁ケ謊≈
?m_Radio4 = 0; ? ?//初始時第四個單“磁ケ謊≈
?//}}AFX_DATA_INIT
終止線程有三種途徑
1.線程可以在自身內部調用AfxEndThread()來終止自身的運行;
?2.可以在線程的外部調用BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode )來強行終止一個線程的運行,然后調用CloseHandle()函數釋放線程所占用的堆棧
?3.改變全局變量,使線程的執行函數返回,則該線程終止。這種方法最安全。
全局函數調用: extern ?UINT ThreadFunc(LPVOID lpParam);


?
在VC中,如果我們想更新UI信息,我們一般調用UpdateData(FALSE),這在
窗口線程中調用是正確的,但如果在后臺進程中這樣調用主窗口的UpdateData(FALSE),則會出現問題,原因很簡單:兩個線程更新同一個窗口的UI信息,會引起UI的線程安全問題,當然也可以更多的線程。
我們可以借助消息機制,來實現多線程的UI更新問題。當線程要更新主窗口的UI時,發送一個自定義消息給主窗口,主窗口在消息處理中UpdateData(FALSE);
因為消息的處理采取隊列形式,挨個處理,線程安全是肯定的!
主窗口:
.h文件:
?
afx_msg ?LRESULT OnUpdateData(LPARAM lParam, WPARAM wParam);
.cpp文件:


BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
? ON_MESSAGE(WM_UPDATEDATA, OnUpdateData)
END_MESSAGE_MAP()


#define WM_UPDATEDATA ? WM_USER + 1
LRESULT OnUpdateData(LPARAM lParam, WPARAM wParam)
{
? return UpdateData(FALSE);
}


線程:
SendMessage(WM_UPDATEDATA)
或者
SendMessageW(hMainWnd, WM_UPDATEDATA, 0, 0)
?
更改XP風格的程序:
?
The following steps introduces XP Theme Style to your project:
Insert Resource, choose "Custom", input "24" (without quotes) as resource type
Copy and paste the following XML sheets into the editor.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity processorArchitecture="x86" version="5.1.0.0" type="win32" name="test.exe"/> <description>Test Application</description> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="x86"/> </dependentAssembly> </dependency> </assembly>
You can replace test.exe and Test Application with any string you like. This will not affect the behaviour of the application.
Change resource ID to 1.
Add calls to InitCommonControls() in your WinMain(). Don't forget to include commctrl.h and link comctl32.lib. Rebuild your project, all done :-)
This special resource type is only recognized by Windows XP. In any other version of Windows (Windows 9x/NT/2000), the program simply runs as before.
You can also create a manifest file with the same name of the EXE file, plus an extension .manifest, which contains the same lines as the ones above. For our test.exe, the manifest file is test.exe.manifest.
Excel中的NULL值,應該用ISNULL來判斷
?sSql="select Name,Code,Price,Date,Market,Total,[M_Weight(%)],[Re_Weight(%)],[PE(T)],[Profit(T)],[Profit(TTM)],[PE(TTM)] from [HSsheet$] where ISNULL([GICS_4]) ?and ISNULL([GICS_C4]) and Date='"+sDate+"'";


ComboBox的用法: ? http://www.codeproject.com/KB/combobox/combobox_tut.aspx
?打開對話框并復制文件:
? ? ?CFile ? file; ?
? ? ? CString ? m_FileName; ?
? ? ? CFileDialog ? m_FileOpen(FALSE,".mdb",NULL,OFN_OVERWRITEPROMPT,"Result ? Files(*.mdb)|*.mdb|所有文件(*.*)|*.*||"); ?
? ? ? if(m_FileOpen.DoModal()==IDOK){ ?
? ? ? m_FileName=m_FileOpen.GetPathName(); ?
? ? ? } ?
? ?
? ? ? CString ? m_Path=m_FileName.Left(m_FileName.ReverseFind('\\')); ?
? ?
? ? ? CString ? strFileName="C:\\project\\Files\\Result.mdb"; ?
? ?
? ? ? LPCTSTR ? lpNewFileName ? = ? (LPCTSTR)(m_FileName); ?
? ? ? int ? a=CopyFile( ?
? ? ? (LPCTSTR)strFileName, ? ? // ? pointer ? to ? name ? of ? an ? existing ? file ?
? ? ? m_FileName, ? ? // ? pointer ? to ? filename ? to ? copy ? to ?
? ? ? FALSE ? ? ? ? ? ? // ? flag ? for ? operation ? if ? file ? exists ?
? ? ? ); ?
找到窗口中的控件:
? // ? TODO: ? Add ? your ? control ? notification ? handler ? code ? here ?
? ? ? UINT ? k=WinExec("rundll32.exe ? shell32.dll,Control_RunDLL ? desk.cpl",SW_SHOW); ?
? ? ? if(k<32) ?
? ? ? { ?
? ? ? CString ? x; ?
? ? ? x.Format("%d",k); ?
? ? ? MessageBox(x); ? ? ? ? ? ? ? ? ? ? // ? 要在error后返回,下同 ?
? ? ? } ?
? ? ? HWND ? wd=::FindWindow(NULL,"顯示 ? 屬性"); ?
? ? ? if ? (wd==NULL) ?
? ? ? MessageBox("Error1"); ?
? ? ? ::ShowWindow(wd,SW_HIDE); ?
? ?
? ? ? HWND ? wtd=FindWindowEx(wd,NULL,"SysTabControl32",NULL); ?
? ? ? if ? (wtd==NULL) ?
? ? ? MessageBox("Error2"); ?
? ?
? ? ? TabCtrl_SetCurFocus(wtd,2); ?
? ?
? ? ? HWND ? wd1=FindWindowEx(wd,NULL,NULL,"外觀"); ?
? ? ? if ? (wd1==NULL) ?
? ? ? MessageBox("Error3"); ?
? ? ? HWND ? cb1=FindWindowEx(wd1,NULL,"ComboBox",NULL); ?
? ? ? if ? (cb1==NULL) ?
? ? ? MessageBox("Error4"); ?
? ? ? ::SendMessage(cb1,CB_SELECTSTRING,-1,(long)"淡綠色"); ?
? ? ? long ? id=::GetDlgCtrlID(cb1); ?
? ? ? ::SendMessage(wd1,WM_COMMAND, ? MAKELONG(id,CBN_SELCHANGE),(long)cb1); ?
? ? ? HWND ? cb2=FindWindowEx(wd1,cb1,"ComboBox",NULL); ?
? ? ? if ? (cb2==NULL) ?
? ? ? MessageBox("Error5"); ?
? ? ? ?
? ? ? //同上可在這修改項目 ?
? ? ? // ? 或其它屬性 ?
? ? ? HWND ? bb1=FindWindowEx(wd,NULL,NULL,"確定"); ?
? ? ? if ? (bb1==NULL) ?
? ? ? MessageBox("Error6"); ?
? ? ? id=::GetDlgCtrlID(bb1); ?
? ? ? ::SendMessage(wd,WM_COMMAND, ? MAKELONG(id,BN_CLICKED),(long)bb1); ?
?
CTime或者COleDateTime,Format方法的使用
關鍵詞: CTime ? ?COleDateTime ? ?Format ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
CTime ct = CTime::GetCurrentTime();
CString str = ct.Format("%Y-%m_%d %H-%M-%S");
輸出為:str="2006-04-23 15-21-30"
%a
Abbreviated weekday name
%A
Full weekday name
%b
Abbreviated month name
%B
Full month name
%c
Date and time representation appropriate for locale
%d
Day of month as decimal number (01 – 31)
%H
Hour in 24-hour format (00 – 23)
%I
Hour in 12-hour format (01 – 12)
%j
Day of year as decimal number (001 – 366)
%m
Month as decimal number (01 – 12)
%M
Minute as decimal number (00 – 59)
%p
Current locale's A.M./P.M. indicator for 12-hour clock
%S
Second as decimal number (00 – 59)
%U
Week of year as decimal number, with Sunday as first day of week (00 – 53)
%w
Weekday as decimal number (0 – 6; Sunday is 0)
%W
Week of year as decimal number, with Monday as first day of week (00 – 53)
%x
Date representation for current locale
%X
Time representation for current locale
%y
Year without century, as decimal number (00 – 99)
%Y
Year with century, as decimal number
%z, %Z
Either the time-zone name or time zone abbreviation, depending on registry settings; no characters if time zone is unknown
%%
Percent sign
// Example for CTime::Format and CTime::FormatGmt
CTime t( 1999, 3, 19, 22, 15, 0 );
// 10:15 PM March 19, 1999
CString s = t.Format( "%A, %B %d, %Y" );
ATLASSERT( s == "Friday, March 19, 1999" );
請問如何讓vc程序在沒有安裝vc 機子上運行
?有三種方式可以解決
1:采用靜態連接模式發布執行文件:這個alt+f9看設置
2:采用打包模式發布安裝程序
3:就是采用DEPENDS.EXE工具(vc6自帶的)打開執行文件,查看運行所需動態庫,把這些都與執行文件放在一起發布
前兩種如樓上幾位說的
?
Double變量和分數相乘時候要注意1/4應該表示成1.0/4.
multimon.h頭文件的include比較例外,格式如下:


#pragma comment(linker, "/FORCE:MULTIPLE")
#pragma comment(linker, "/OPT:NOREF")
#define COMPILE_MULTIMON_STUBS
#include "multimon.h"
一些常用的代碼:
http://sjtu.blog.sohu.com/77568810.html
ListBox的使用:
http://sjtu.blog.sohu.com/79741748.html


響應CEdit控件的鼠標單擊事件:
BOOL CStockDLG::PreTranslateMessage(MSG* pMsg)
{
?// TODO: Add your specialized code here and/or call the base class
?switch(pMsg->message) ?
?{ ?
?case ? WM_LBUTTONDOWN:
? {
? ?CPoint ? pt; ?
? ?GetCursorPos(&pt); ?
? ?ScreenToClient(&pt);
? ?
? ?CRect rect;
? ?GetDlgItem(IDC_STOCKID)->GetWindowRect(&rect);
? ?ScreenToClient(&rect);
? ?if(rect.PtInRect(pt))
? ?{
? ? ? ? ? ?PostMessage(WM_OPENSSDLG,0,0);
? ?}
? ?break;
? }
?} ?
?
?return CDialog::PreTranslateMessage(pMsg);
}
PreTranslateMessage中不能使用domodal的原因:?
mfc的PreTranslateMessage是由一個全局函數AfxInternalPreTranslateMessage來執行的,這個函數是不可重入的,也就是不能嵌套調用。 ?
? ?
? 你在PreTranslateMessage中DoModal,那么DoModal中又有自己的消息循環,必然會導致AfxInternalPreTranslateMessage的重入。 ??
? ??
?解決方法:
void ? CMyWnd::OnKeyUp(UINT ? nChar,UINT ? nRepCnt,UINT ? nFlags) ?
? { ?
? ? ? CWnd::OnKeyUp(nChar,nRepCnt,nFlags); ?
? ? ? if(nChar ? == ? VK_SPACE) ?
? ? ? { ?
? ? ? ? ? CChsRollDlg ? dlg; ?
? ? ? ? ? dlg.DoModal(); ?
? ? ? } ?
? } ?
? ?
? 改成這樣 ?
? ?
? void ? CMyWnd::OnKeyUp(UINT ? nChar,UINT ? nRepCnt,UINT ? nFlags) ?
? { ?
? ? ? CWnd::OnKeyUp(nChar,nRepCnt,nFlags); ?
? ? ? if(nChar ? == ? VK_SPACE) ?
? ? ? ? ? PostMessage ? (WM_USER, ? 0, ? 0); ?
? } ?
? ?
? // ? WM_USER的消息函數 ?
? void ? CMyDlg::OnUser ? (...) ?
? { ?
? ? ? CChsRollDlg ? dlg; ?
? ? ? dlg.DoModal(); ?
? }; ?
屏蔽Dialog的Enter和ESC鍵:
BOOL CAShareDlg::PreTranslateMessage(MSG* pMsg)
{
?// TODO: Add your specialized code here and/or call the base class
? ? if(pMsg -> message == WM_KEYDOWN)
?{
? ? ? ? if(pMsg -> wParam == VK_ESCAPE)
? ?return TRUE;
? if(pMsg -> wParam == VK_RETURN)
? ?return TRUE;
?} ?
?return CDialog::PreTranslateMessage(pMsg);
}
點擊對話框外面時候對話框關閉的方法:
if(!bActive)
? if(!bOkClosed)
? EndDialog(IDCANCEL);
WM_NCACTIVATE響應 ?
? wParam參數為FALSE時關閉
一個很好用的CXFileDialog:
http://www.codeproject.com/KB/dialog/xfiledialog.aspx
MFC學習總結 (90個技巧)
http://www.cnblogs.com/cy163/archive/2006/10/18/532871.html
如何讓沒有TitleBar的對話框,能響應任務欄左鍵最小化事件以及任務欄右鍵菜單?
?ModifyStyle(0, ? WS_SYSMENU);
?ModifyStyle(0, ? WS_MINIMIZEBOX); ?
運行Dos命令并判斷其運行結束:
?STARTUPINFO ? si; ?
?PROCESS_INFORMATION ? pi; ?
?ZeroMemory( ? &si, ? sizeof(si) ? ); ?
?si.cb ? = ? sizeof(si); ?
?ZeroMemory( ? &pi, ? sizeof(pi) ? ); ?
?si.dwFlags ? = ? STARTF_USESHOWWINDOW; ? ? //設置隱藏執行窗口 ?
?si.wShowWindow ? = ? SW_HIDE; ?
? ?
? ? CreateProcess(NULL, ? (char*)(LPCTSTR)strCmd, ? NULL, ? NULL, ? FALSE, ? 0, ? NULL, ? NULL, ? &si, ? &pi);
?while(true)
?{
? if(WaitForSingleObject(pi.hProcess,0)==WAIT_OBJECT_0)
? ?break;
?}
Vector的序列化:
? 保存 ?
? copy(vi.begin(), ? vi.end(), ? ostream_iterator<int>(...)); ?
? ...省略號處可以改為ofstream的話,就將vi對象中的各個值存入ofstream所幫定的文件對象; ?
? ?
? 取出 ?
? copy(istream_iterator(ifstream(...)), ? ifstream_iterator(ifstream_iterator<int> ? eof, ? back_insert(vi) ? ); ?
? ?
? 此處是從文件中順序讀入vi的值,并且使用back_insert()方法 ? ?
========

VC++常用編程技巧



1如何獲取應用程序的實例句柄?


應用程序的實例句柄保存在CWinApp m_hInstance 中,可以這么調用AfxGetInstancdHandle獲得句柄.


HANDLE hInstance=AfxGetInstanceHandle()


2 如何通過代碼獲得應用程序主窗口的指針?
主窗口的 指針保存在CWinThread::m_pMainWnd中,調用AfxGetMainWnd實現。


AfxGetMainWnd() ->ShowWindow(SW_SHOWMAXMIZED) //使程序最大化.


3 如何在程序中獲得其他程序的圖標?
兩種方法:


· ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SDK函數 SHGetFileInfo 或使用 ExtractIcon獲得圖標資源的handle.


void CSampleView:


OnDraw(CDC * pDC)


{


if( :: SHGetFileInfo(_T("c:\\pwin95\\notepad.exe"),0,


&stFileInfo,sizeof(stFileInfo),SHGFI_ICON))


{


pDC ->DrawIcon(10,10,stFileInfo.hIcon)


}


}


· ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SDK函數 SHGetFileInfo 獲得有關文件的很多信息,如大小圖標,屬性,類型等.


void CSampleView:: OnDraw(CDC *pDC)


{


HICON hIcon=:: ExtractIcon(AfxGetInstanceHandle(),_T


("NotePad.exe"),0)


if (hIcon &&hIcon!=(HICON)-1)


pDC->DrawIcon(10,10,hIcon)


}


?
說明: 獲得notepad.exe的路徑正規上來說用GetWindowsDirectory函數得到,如果是調用 win95下的畫筆,應該用訪問注冊表的方法獲得其路徑,要作成一個比較考究的程序,考慮應該全面點.


4 如何編程結束應用程序?
這是個很簡單又是編程中經常要遇到的問題. 向窗口發送 WM_CLOSE消息,調用 CWnd::OnClose成員函數.允許對用戶提示是否保存修改過的數據.


//發送關閉窗口消息


AfxGetMainWindow()->SendMessage(WM_CLOSE)


?


//通過標題欄尋找需要關閉的窗口,然后關閉找到的窗口


void Terminate_Window(LPCSTR pCaption)


{


CWnd *pWnd=Cwnd::FindWindow(NULL,pCaption)




if (pWnd)


pWnd ->SendMessage(WM_CLOSE)


}


說明: FindWindow函數不是提倡的做法,因為它無法處理標題欄自動改變,比如我們要檢測 Notepad是不是已運行而事先不知道Notepad的標題欄,這時FindWindow就無能為力了,可以通過枚舉 windows任務列表的辦法來實現。在機械出版社”Windows 95 API開發人員指南”一書有比較詳細的介紹,這里就不再多說了。


5 怎樣加載其他的應用程序?
三個SDK函數 winexec, shellexecute,createprocess可以使用。 WinExec最簡單,兩個參數,前一個指定路徑,后一個指定顯示方式.后一個參數值得說一下,比如泥用 SW_SHOWMAXMIZED方式去加載一個無最大化按鈕的程序,就是Neterm,calc等等,就不會出現正常的窗體,但是已經被加到任務列表里了。


ShellExecute較 WinExex靈活一點,可以指定工作目錄,下面的Example就是直接打開 c:\temp\1.txt,而不用加載與 txt文件關聯的應用程序,很多安裝程序完成后都會打開一個窗口,來顯示Readme or Faq,我猜就是這么作的啦.


ShellExecute(NULL,NULL,_T("1.txt"),NULL,_T("c:\\temp"),SW_SHOWMAXMIZED)


CreateProcess最復雜,一共有十個參數,不過大部分都可以用NULL代替,它可以指定進程的安全屬性,繼承信息,類的優先級等等.來看個很簡單的Example:


STARTUPINFO stinfo


//啟動窗口的信息


PROCESSINFO procinfo //進程的信息
?


CreateProcess(NULL,_T("notepad.exe"),NULL,NULL.FALSE,


NORMAL_PRIORITY_




CLASS,NULL,NULL, &stinfo,&procinfo)
?


6 如何確定應用程序的路徑?
Use GetModuleFileName 獲得應用程序的路徑,然后去掉可執行文件名。 Example:


TCHAR exeFullPath[MAX_PATH]


GetModuleFileName(NULL,exeFullPath,MAX_PATH)


7 如何獲得各種目錄信息?
Windows目錄: Use “GetWindowsDirectory” Windows下的system目錄: Use “GetSystemDirectory” temp目錄: Use “GetTempPath” 當前目錄: Use “GetCurrentDirectory”


請注意前兩個函數的第一個參數為目錄變量名,后一個為緩沖區后兩個相反


8 如何自定義消息?
(1) 手工定義消息,可以這么寫 #define WM_MY_MESSAGE(WM_USER+100), MS 推薦的至少是 WM_USER+100


(2)寫消息處理函數,用 WPARAM,LPARAM返回LRESULT. LRESULT CMainFrame::OnMyMessage(WPARAM wparam,LPARAM lParam)


9 如何改變窗口的圖標?
向窗口發送 WM_SECTION消息。 Example:


HICON hIcon=AfxGetApp() ->LoadIcon(IDI_ICON)


ASSERT(hIcon)


AfxGetMainWnd() ->SendMessage(WM_SECTION,TRUE,(LPARAM)hIcon)


10 如何改變窗口的缺省風格?
重載 CWnd:: PreCreateWindow 并修改CREATESTRUCT結構來指定窗口風格和其他創建信息.


//Delete "Max" Button and Set Original Window's Position and Size


BOOL CMainFrame:: PreCreateWindow


(CREATESTRUCT &cs)


{


cs.style &=~WS_MAXINIZEMOX


?


cs.x=cs.y=0


cs.cx=GetSystemMetrics(SM_CXSCREEN/2)


cs.cy=GetSystemMetrics(SM_CYSCREEN/2)


?


return CMDIFramewnd ::PreCreateWindow(cs)


}


?


11如何將窗口居中顯示?
調用窗口函數 CWnd::Center_window() Example(1):


Center_Window( ) //Relative to it's parent // Relative to Screen


Example(2):


Center_Window(CWnd:: GetDesktopWindow( ))


//Relative to Application's MainWindow


AfxGetMainWnd( )->Center_Window( );


12 如何讓窗口和 MDI窗口一啟動就最大化和最小化?
先說窗口。 在 InitStance 函數中設定 m_nCmdShow的取值. m_nCmdShow=SW_SHOWMAXMIZED 最大化 m_nCmdShow=SW_SHOWMINMIZED 最小化 m_nCmdShow=SW_SHOWNORMAL 正常方式 MDI窗口: 如果是創建新的應用程序,可以用MFC AppWizard 的Advanced 按鈕并在MDI子窗口風格組中檢測最大化或最小化還可以重載 MDI Window 的PreCreateWindow函數,設置WS_MAXMIZE or WS_MINMIZE 如果從 CMDIChildWnd派生,調用 OnInitialUpdate函數中的 CWnd::Show Window來指定 MDI Child Window的風格。 OnQueryOpen() ,add following code Bool CMainFrame:: OnQueryOpen( ) { Return false } </code>


13 如何使程序保持極小狀態?
這么辦: 在恢復程序窗體大小時,Windows會發送WM_QUERY-OPEN消息,用 ClassWizard設置成員函數 <code cpp>


14 如何限制窗口的大小?
也就是 FixedDialog形式。 Windows發送 WM_GETMAXMININFO消息來跟蹤, 響應它,在 OnGetMAXMININFO 中寫代碼:


15 如何使窗口不可見?
很簡單,用SW_HIDE 隱藏窗口,可以結合 FindWindow,ShowWindow控制.


16 如何使窗口始終在最前方?
BringWindowToTop(Handle) SetWindowPos函數,指定窗口的 最頂風格,用WS_EX_TOPMOST擴展窗口的風格


void ToggleTopMost(CWnd *pWnd)


{


ASSERT_VALID(pWnd)


?


pWnd ->SetWindowPos(pWnd-> GetStyle( ) &WS_EX_TOPMOST)?


?


&wndNoTopMOST: &wndTopMost,0,0,0,0,SSP_NOSIZE|WSP_NOMOVE)


}


17 如何創建一個字回繞的CEditView?
重載CWnd : : PreCreateWindow和修改CREATESTRUCT結構,關閉CEditView對象的ES_AUTOHSCROLL和WS_HSCROLL 風格位, 由于CEditView : : PreCreateWindow顯示設置cs. style,調用基類函數后要修改cs . style。


BOOL CSampleEDitView : : PreCreateWindow (CREATESTRUCT&cs)


{


//First call basse class function .


BOOL bResutl =CEditView : : PreCreateWindow (cs)


?


// Now specify the new window style .


cs.style &= ~ (ES_AUTOHSCROLL |WS_HSCROLL)


return bResult


}


18 通用控件的顯示窗口
MFC提供了幾個CView派生的視窗類,封裝了通用控件的功能,但仍然使用工作框文檔顯示窗口體系結構:CEditView封裝了編輯控件,CTreeView保持了樹列表控件,CListView封裝了列表顯示窗口控件,CRichEditView可以處理多種編輯控件。


19 如何移動窗口?
調用CWnd : : SetWindowPos并指定SWP_NOSIZE標志。目的位置與父窗口有關(頂層窗口與屏幕有關)。調用CWnd : : MoveWindow時必須要指定窗口的大小。


//Move window to positoin 100 , 100 of its parent window .


SetWindowPos (NULL, 100 , 100 , 0 , 0 , SWP_NOSIZE |SWP_NOAORDER)


20 如何重置窗口的大小?
調用CWnd: : SetWindowPos并指定SWP_NOMOVE標志, 也可調用CWnd : : MoveWindow 但必須指定窗口的位置。


// Get the size of the window .


Crect reWindow


GetWindowRect (reWindow )


?


//Make the window twice as wide and twice as tall .


SetWindowPos (NULL , 0 , 0 , reWindow . Width ( ) *2,


?


reWindow . Height () * 2,


SWP_NOMOVE |SWP_NOZORDER )


21如何單擊除了窗口標題欄以外的區域使窗口移動?
當窗口需要確定鼠標位置時Windows向窗口發送WM_NCHITTEST信息,可以處理該信息使Windows認為鼠標在窗口標題上。對于對話框和基于對話的應用程序,可以使用ClassWizard處理該信息并調用基類函數, 如果函數返回HTCLIENT 則表明鼠標在客房區域,返回HTCAPTION表明鼠標在Windows的標題欄中。


UINT CSampleDialog : : OnNcHitTest (Cpoint point )


{


UINT nHitTest =Cdialog: : OnNcHitTest (point )


return (nHitTest = =HTCLIENT)? HTCAPTION : nHitTest


}


?


上述技術有兩點不利之處, 其一是在窗口的客戶區域雙擊時,窗口將極大; 其二, 它不適合包含幾個視窗的主框窗口。還有一種方法,當用戶按下鼠標左鍵使主框窗口認為鼠標在其窗口標題上,使用ClassWizard在視窗中處理WM_LBUTTODOWN信息并向主框窗口發送一個WM_NCLBUTTONDOWN信息和一個單擊測試HTCAPTION。


void CSampleView : : OnLButtonDown (UINT nFlags , Cpoint point


)


{


CView : : OnLButtonDow (nFlags , pont )


?


//Fool frame window into thinking somene clicked


on


its caption bar .


GetParentFrame ( ) —> PostMessage (


WM_NCLBUTTONDOWN ,


HTCAPTION , MAKELPARAM (poitn .x , point .y) )


?


}


該技術也適用于對話框和基于對的應用程序,只是不必調用 CWnd: :GetParentFrame 。


void CSampleDialog : : OnLbuttonDown (UINT nFlags, Cpoint point )


{


Cdialog : : OnLButtonDow (nFlags, goint )


//Fool dialog into thinking simeone clicked on its


caption bar .


PostMessage (WM_NCLBUTTONDOWN , HTCAPTION , MAKELPARM (point.x


, point. y


) )


}


22 如何改變視窗的背景顏色?
Windows向窗口發送一個WM_ERASEBKGND消息通知該窗口擦除背景,可以使用ClassWizard重載該消息的缺省處理程序來擦除背景(實際是畫),并返回TRUE以防止Windows擦除窗口。


//Paint area that needs to be erased.


BOOL CSampleView : : OnEraseBkgnd (CDC* pDC)


{


// Create a pruple brush.


CBrush Brush (RGB (128 , 0 , 128) )


?


// Select the brush into the device context .


CBrush* pOldBrush = pDC—>SelcetObject (&brush)


?


// Get the area that needs to be erased .


CRect reClip


pDC—>GetCilpBox (&rcClip)


//Paint the area.


pDC—> PatBlt (rcClip.left , rcClip.top , rcClip.Width ( ) , rcClip.Height( ) , PATCOPY )


?


//Unselect brush out of device context .


pDC—>SelectObject (pOldBrush )


?


// Return nonzero to half fruther processing .


return TRUE


}


23 如何改變窗口標題?
調用CWnd : : SetWindowText可以改變任何窗口(包括控件)的標題。


//Set title for application's main frame window .


AfxGetMainWnd ( ) —> SetWindowText (_T("Application title") )


//Set title for View's MDI child frame window .


GetParentFrame ( ) —> SetWindowText ("_T ("MDI Child Frame new title")


)


//Set title for dialog's push button control.


GetDigitem (IDC_BUTTON) —> SetWindowText (_T ("Button new title ") )


?


如果需要經常修改窗口的標題(注:控件也是窗口),應該考慮使用半文檔化的函數AfxSetWindowText。該函數在AFXPRIV.H中說明,在WINUTIL.CPP中實現,在聯機幫助中找不到它,它在AFXPRIV.H中半文檔化, 在以后發行的MFC中將文檔化。 AfxSetWindowText的實現如下:


voik AFXAPI AfxSetWindowText (HWND hWndCtrl , LPCTSTR IpszNew )


{


itn nNewLen= Istrlen (Ipaznew)


TCHAR szOld [256]


//fast check to see if text really changes (reduces


flash in the


controls )


if (nNewLen >_contof (szOld)


|| : : GetWindowText (hWndCrtl, szOld , _countof (szOld) !=nNewLen


|| Istrcmp (szOld , IpszNew)! = 0


{


//change it


: : SetWindowText(hWndCtrl , IpszNew )


}


}


24 如何防止主框窗口在其說明中顯示活動的文檔名
創建主框窗口和MDI子窗口進通常具有FWS_ADDTOTITLE風格位,如果不希望在說明中自動添加文檔名, 必須禁止該風格位, 可以使用ClassWizard重置


CWnd: : PreCreateWindow并關閉FWS_ADDTOTITLE風格。


BOOL CMainFrame : : PreCreateWindow (CREATESTRUCT&cs)


{


//Turn off FWS_ADDTOTITLE in main frame .


cs.styel & = ~FWS_ADDTOTITLE


return CMDIFrameWnd : : PreCreateWindow (cs )


}


關閉MDI子窗口的FWS _ADDTOTITLE風格將創建一個具有空標題的窗口,可以調用CWnd: : SetWindowText來設置標題。記住自己設置標題時要遵循接口風格指南。


25 如何獲取有關窗口正在處理的當前消息的信息?
調用CWnd: : GetCurrentMessage可以獲取一個MSG指針。例如,可以使用ClassWizard將幾個菜單項處理程序映射到一個函數中,然后調用GetCurrentMessage來確定所選中的菜單項。


viod CMainFrame : : OnCommmonMenuHandler ( )


{


//Display selected menu item in debug window .


TRACE ("Menu item %u was selected . \n" ,GetCruuentMessage ( ) —> wParam )


}


26 如何創建一個不規則形狀的窗口 ?
可以使用新的SDK函數SetWindowRgn。該函數將繪畫和鼠標消息限定在窗口的一個指定的區域,實際上使窗口成為指定的不規則形狀。使用AppWizard創建一個基于對的應用程序并使用資源編輯器從主對話資源中刪除所在的缺省控件、標題以及邊界。給對話類增加一個CRgn數據成員,以后要使用該數據成員建立窗口區域。


Class CRoundDlg : public CDialog


{





private :


Crgn m_rgn : // window region





}


修改OnInitDialog函數建立一個橢圓區域并調用SetWindowRgn將該區域分配給窗口:


BOOL CRoundDlg : : OnInitDialog ( )


{


CDialog : : OnInitDialog ( )


?


//Get size of dialog .


CRect rcDialog


GetClientRect (rcDialog )


?


// Create region and assign to window .


m_rgn . CreateEllipticRgn (0 , 0 , rcDialog.Width( ) , rcDialog.Height ( ) )


SetWindowRgn (GetSafeHwnd ( ) , (HRGN) m_ rgn ,TRUE )


?


return TRUE


}


通過建立區域和調用SetWindowRgn,已經建立一個不規則形狀的窗口,下面的例子程序是修改OnPaint函數使窗口形狀看起來象一個球形體。


voik CRoundDlg : : OnPaint ( )


{


CPaintDC de (this) // device context for painting


.


//draw ellipse with out any border


dc. SelecStockObject (NULL_PEN)


//get the RGB colour components of the sphere color


COLORREF color= RGB( 0 , 0 , 255)


BYTE byRed =GetRValue (color)


BYTE byGreen = GetGValue (color)


BYTE byBlue = GetBValue (color)


?


// get the size of the view window


Crect rect


GetClientRect (rect)


?


// get minimun number of units


int nUnits =min (rect.right , rect.bottom )


?


//calculate he horiaontal and vertical step size


float fltStepHorz = (float) rect.right /nUnits


float fltStepVert = (float) rect.bottom /nUnits




int nEllipse = nUnits/3 // calculate how many to


draw


int nIndex


// current ellipse that is being draw


?


CBrush brush


// bursh used for ellipse fill color


CBrush *pBrushOld // previous


brush that was selected into dc


//draw ellipse , gradually moving towards upper-right


corner


for (nIndex = 0 nIndes < + nEllipse nIndes++)


{


//creat solid brush


brush . CreatSolidBrush (RGB ( ( (nIndex*byRed ) /nEllipse ).


( ( nIndex * byGreen ) /nEllipse ), ( (nIndex * byBlue)


/nEllipse ) ) )


?


//select brush into dc


pBrushOld= dc .SelectObject (&brhsh)


?


//draw ellipse


dc .Ellipse ( (int) fltStepHorz * 2, (int) fltStepVert * nIndex ,


rect. right -( (int) fltStepHorz * nIndex )+ 1,


rect . bottom -( (int) fltStepVert * (nIndex *2) ) +1)


?


//delete the brush


brush.DelecteObject ( )


}


}


最后,處理WM_NCHITTEST消息,使當擊打窗口的任何位置時能移動窗口。


UINT CRoundDlg : : OnNchitTest (Cpoint point )


{


//Let user move window by clickign anywhere on thewindow .


UINT nHitTest = CDialog : : OnNcHitTest (point)


rerurn (nHitTest = = HTCLIENT)? HTCAPTION: nHitTest


?


}


27 如何在代碼中獲取工具條和狀態條的指針?
缺省時,工作框創建狀態條和工具條時將它們作為主框窗口的子窗口,狀態條有一個AFX_IDW_STATUS_BAR標識符,工具條有一個 AFX_IDW_TOOLBAR標識符,下例說明了如何通過一起調用CWnd: : GetDescendantWindow和AfxGetMainWnd來獲取這些子窗口的指針:


//Get pointer to status bar .


CStatusBar * pStatusBar = (CStatusBar *) AfxGetMainWnd ( )


->GetDescendantWindow(AFX_IDW_STUTUS_BAR)


//Get pointer to toolbar .


CToolBar * pToolBar = (CToolBar * ) AfxGetMainWnd ( )


->GetDescendantWindow(AFX_IDW_TOOLBAR)?


?

========

VC編程中20種各種編程技巧和方法

http://blog.csdn.net/worldy/article/details/13771607


1. ? ?如何激活當前屏幕保護程序
2. ? ?如何禁止/啟用屏幕保護及電源管理
3. ? ?如何激活和關閉IE瀏覽器
4. ? ?如何給樹控件加入工具提示
5. ? ?如何獲取系統信息框的路徑
6. ? ?如何直接運行一個資源中的程序
7. ? ?如何遍歷整個目錄
8. ? ?如何禁止/啟用系統熱鍵
9. ? ?如何隱藏/顯示WINDOWS系統任務欄
10. ? ?如何實現窗口到系統區圖標間的動畫效果
11. ? ?如何判斷當前操作系統的版本
12. ? ?如何在指定矩形框內水平/垂直顯示多行文字
13. ? ?如何在指定矩形中旋轉顯示文字
14. ? ?如何將32 x 32像素圖標轉換為16 x 16像素值的圖標
15. ? ?如何建立一個灰度級圖標
16. ? ?如何按指定角度旋轉顯示內存位圖(用法和BitBlt類似)
17. ? ?如何將指定的窗體,以位圖形式復制到系統剪切板上
18. ? ?如何替換HBITMAP中的顏色值
19. ? ?如何轉換并保存位圖
20. ? ?如何獲取局域網上計算機名及它們的IP地址



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<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. ? ?如何激活和關閉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 <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, &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 <windows.h>
#include <shlobj.h>


//瀏覽目錄.
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()中相應設置<ETO_CLIPPED 和 ETO_OPAQUE>
///
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();


總結

以上是生活随笔為你收集整理的VC++ 常用编程技巧总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。