1. 窗口最大化、最小化的實現
當我們不能用標題欄的最大化、最小化及恢復按鈕而又需在其他的地方實現這些功能,可以在指定的消息處理函數里添加:
WINDOWPLACEMENT wndpl;
WINDOWPLACEMENT *pwndpl;
pwndpl = &wndpl;
GetWindowPlacement(pwndpl);
pwndpl->showCmd = SW_SHOWMINMIZED; //實現窗口最小化
SetWindowPlacement(pwndpl);
其中GetWindowPlacement()函數獲取當前窗口布局的結構WINDOWPLACEMENT的結構變量指針,結構WINDOWPLACEMENT定義為:
typedef struct tagWINDOWPLACEMENT{
UINT length;
UINT flags;
UINT showCmd;
POINT ptMinPosition;
POINT ptMaxPosition;
RECT rcNormalPosition;
}WINDOWPLACEMENT;
其中的成員變量showCmd確定當前窗口的狀態,取值一般為:
·SW_HIDE:隱藏窗口
·SW_MINIMIZE:最小化指定的窗口
·SW_RESTORE:恢復原來的大小
·SW_SHOW:以原來的大小激活并顯示
·SW_SHOWMAXIMIZED:激活并最大化窗口
SetWindowPlacement()函數就是按WINDOWPLACEMENT的設置來顯示窗口
2. 為什么要使用GetSafeHwnd()函數
當我們想得到一個窗口對象(CWnd的派生對象)指針的句柄(HWND)時,最安全的方法是使用GetSafeHwnd()函數,通過下面的例子來看其理由:
CWnd *pwnd = FindWindow(“ExploreWClass”,NULL); //希望找到資源管理器
HWND hwnd = pwnd->m_hwnd; //得到它的HWND
這樣的代碼當開始得到的pwnd為空的時候就會出現一個“General protection error”,并關閉應用程序,因為一般不能對一個NULL指針訪問其成員,如果用下面的代碼:
CWnd *pwnd = FindWindow(“ExploreWClass”,NULL); //希望找到資源管理器
HWND hwnd = pwnd->GetSafeHwnd(); //得到它的HWND
就不會出現問題,因為盡管當pwnd是NULL時,GetSafeHwnd仍然可以用,只是返回NULL,通過GetSafeHwnd()的實現代碼就更清楚了:
_AFXWIN_INLINE HWND CWnd::GetSafeHwnd() const
{
return this == NULL?NULL:m_hWnd;
}
3. 如何使程序處于極小狀態
如果我們不想讓程序的窗口被別人看見,就可以讓它保持在極小狀態:在恢復程序窗口的時候,Window會發送WM_QUERYOPEN消息,只要在其消息處理函數里返回false就可以了。
BOOL CmainFrame::OnQueryOpen()
{
return false;
}
4. 如何禁止和能用關閉按鈕
Cmenu *pmenu = AfxGetMainWnd()->GetSystemMenu(FALSE);
if(pmenu)
{
pmenu->EnableMenuItem(SC_CLOSE,MF_BYCOMMAND|MF_GRAYED);
}
恢復時只需將MF_GRAYED改為MF_ENABLED
5. 如何在程序中延時
方法一:
使用sleep函數,如延時2秒,用sleep(2000);
方法二:
使用sleep函數的不利在于延時期間不能處理其他的消息,如果時間太長,就好象死機一樣,利用ColeDateTime類和ColeDateTimeSpan類實現延時就不會出現那樣的問題:
ColeDateTime start_time = ColeDateTime::GetCurrentTime();
ColeDateTimeSpan end_time = ColeDateTime::GetCurrentTime()-start_time;
While(end_time.GetTotalSeconds() <= 2)
{
MSG msg;
GetMessage(&msg,NULL,0,0);
PreTranslateMessage(&msg);
End_time = ColeDateTime::GetCurrentTime-start_time;
}
這樣在延時的時候我們也能夠處理其他的消息。
看了論壇里的一些總結文章很好,我把里面沒有怎么看到的也寫了一點點出來,不知道有沒有重復,希望能有些微的作用.
本文引用通告地址: http://blog.csdn.net/laiyiling/services/trackbacks/22293.aspx
6. 如何創建可伸縮的對話框
在進行對話框的設計時,有時候我們需要設計可伸縮的對話框,當用戶按下某個按鈕時彈出或隱藏對話框的下半部分。
(1)、首先在對話框中建立一個圖片控件把ID設為IDC_DIVIDER,Type設置為矩形,Color設置為黑色,并將其設定為一線狀,拖放在適當的位置做為伸縮對話框的分割線,屬性設為不可見。
(2)、實現的原理:先獲取對話框的尺寸大小,然后根據的位置來確定縮減后的對話框大小,其實對話框伸縮的變化就是的值,在縮減對話框后,我們要使不可見的部分控件被禁止,以禁止加速鍵和TAB鍵對其的操作,在擴展對話框后,原來被禁止的控件又要使能。
先在對話框上的伸縮按鈕添加單擊消息處理函數:
void C***Dlg::OnButtonExpand()
{
static int bexpand = FALSE; //設初始時為已擴展的
ExpandDialog(IDC_DIVIDER,bexpand);//調用擴展或縮減處理函數
Bexpand = !bexpand;//狀態取反,為下次的單擊處理準備
}
//在對話框中添加一個成員函數ExpandDialog,用于擴展或縮減
void C***Dlg::ExpandDialog(int nResourceID,BOOL bexpand)
{
//參數nResourceID表示分割線的ID
//參數bexpand為TRUE時表示要擴展對話框,否則縮減對話框
static CRect rcLarge;
static CRect rcSmall;
if(rcLarge.IsRectNULL()) //首次使用時記下對話框的最大、最小尺寸
{
CRect rcLandmark;
CWnd *pwndLand = GetDlgItem(nResourceID);
ASSERT(pwndLand);
GetWindowRect(rcLarge);
pwndLand->GetWindowRect(rcLandmark);
rcSmall = rcLarge;
rcSmall.bottom = rcLandmark.bottom;
}
if(bexpand)
{
SetWindowPos(NULL,0,0,rcLarge.Width(),rcLarge.Height(),
SWP_NOMOVE|SWP_NOZORDER);
EnableVisible();
}
else
{
SetWindowPos(NULL,0,0,rcSmall.Width(),rcSmall.Height(),
SWP_NOMOVE|SWP_NOZORDER);
EnableVisible();
}
}
//在對話框中添加一個成員函數EnableVisible,用于能用和禁止部分控件
void C***Dlg:: EnableVisible()
{
CWnd *pwnd = GetDlgItem(GW_CHILD);
CRect retest;
CRect rcControl;
CRect rcShow;
GetWindowRect(rcShow);
While(pwnd != NULL)
{
pwnd->GetWindowRect(rcControl);
if(rcTest.IntersectRect(rcShow,rcControl))
pwnd->EnableWindow(TRUE);
else
pwnd->EnableWindow(FALSE);
pwnd = pwnd->GetWindow(GW_HWNDNEXT);
}
}
7. 為什么有RichEdit控件的對話框無法顯示
如果在對話框上放一個RichEdit控件,往往發現對話框卻無法正常顯示,這是因為應用程序還沒有為RichEdit控件的編輯功能做好準備,解決辦法就是在應用程序的InitInstance()函數調用AfxInitRichEdit()函數初始化RichEdit控件
8. 如何指定對話框的默認按鈕
當建立一個對話框的時候,在默認條件下,確定按鈕(IDOK)是默認按鈕,如果需要改變默認的按鈕有兩種方法:
其一:直接在確定按鈕(IDOK)的屬性里去掉Default button風格的選項
其二:在運行的時候用代碼實現,如:
//去掉確定按鈕(IDOK)的默認按鈕
CButton *pokbutton = (CButton *)GetDlgItem(IDOK);
Pokbutton->ModifyStyle(BS_DEFPUSHBUTTON,0);
//添加IDCANCEL的默認按鈕風格
CButton *pcancelbutton = (CButton *)GetDlgItem(IDCANCEL);
pcancelbutton->SetButtonStyle(BS_DEFPUSHBUTTON);本文引用通告地址: http://blog.csdn.net/laiyiling/services/trackbacks/22294.aspx
1. 顯示和隱藏標題欄
方法一:使用API實現
//隱藏TitleBar
LONG lStyle = ::GetWindowLong(this->m_hWnd, GWL_STYLE);
::SetWindowLong(this->m_hWnd, GWL_STYLE, lStyle & ~WS_CAPTION);
::SetWindowPos(this->m_hWnd, NULL, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
// 顯示TitleBar
::SetWindowLong(this->m_hWnd, GWL_STYLE, lStyle | WS_CAPTION);
::SetWindowPos(this->m_hWnd, NULL, 0, 0, 0, 0,??SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
方法二:使用CWnd成員函數ModifyStyle實現
// 隱藏TitleBar
ModifyStyle(WS_CAPTION, 0, SWP_FRAMECHANGED);
// 顯示TitleBar
ModifyStyle(0, WS_CAPTION, SWP_FRAMECHANGED);
2 . 怎么用SendMessage()來發送消息來清空它的內容??
HWND hEditWnd=GetDlgItem(IDC_EDIT1)->GetSafeHwnd();
::SendMessage(hEditWnd,WM_SETTEXT,(WPARAM)0,(LPARAM)"");
3. 彈出文件的屬性窗口
SHELLEXECUTEINFO ShExecInfo ={0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_INVOKEIDLIST ;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = "properties";
ShExecInfo.lpFile = "c:\"; //也可以是文件
ShExecInfo.lpParameters = "";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_SHOW;
ShExecInfo.hInstApp = NULL;
ShellExecuteEx(&ShExecInfo);
4. 刪除一個目錄下的所有文件
BOOL DeleteDirectory(LPCTSTR DirName)
{
CFileFind tempFind; //聲明一個CFileFind類變量,以用來搜索
char tempFileFind[200]; //用于定義搜索格式
sprintf(tempFileFind,"%s\\*.*",DirName);
//匹配格式為*.*,即該目錄下的所有文件
BOOL IsFinded=(BOOL)tempFind.FindFile(tempFileFind);
//查找第一個文件
while(IsFinded)
{
IsFinded=(BOOL)tempFind.FindNextFile(); //遞歸搜索其他的文件
if(!tempFind.IsDots()) //如果不是"."目錄
{
char foundFileName[200];
strcpy(foundFileName,tempFind.GetFileName().GetBuffer(200));
if(tempFind.IsDirectory()) //如果是目錄,則遞歸地調用
{ //DeleteDirectory
char tempDir[200];
sprintf(tempDir,"%s\\%s",DirName,foundFileName);
DeleteDirectory(tempDir);
}
else
{ //如果是文件則直接刪除之
char tempFileName[200];
sprintf(tempFileName,"%s\\%s",DirName,foundFileName);
DeleteFile(tempFileName);
}
}
}
tempFind.Close();
if(!RemoveDirectory(DirName)) //刪除目錄
{
AfxMessageBox("刪除目錄失敗!",MB_OK);
return FALSE;
}
return TRUE;
}
5.? lib和dll文件的區別和聯系
.dll是在你的程序運行的時候才連接的文件,因此它是一種比較小的可執行文件格式,.dll還有其他的文件格式如.ocx等,所有的.dll文件都是可執行。
.lib是在你的程序編譯連接的時候就連接的文件,因此你必須告知編譯器連接的lib文件在那里。一般來說,與動態連接文件相對比,lib文件也被稱為是靜態連接庫。當你把代碼編譯成這幾種格式的文件時,在以后他們就不可能再被更改。如果你想使用lib文件,就必須:
1? 包含一個對應的頭文件告知編譯器lib文件里面的具體內容
2? 設置lib文件允許編譯器去查找已經編譯好的二進制代碼
如果你想從你的代碼分離一個dll文件出來代替靜態連接庫,仍然需要一個lib文件。這個lib文件將被連接到程序告訴操作系統在運行的時候你想用到什么dll文件,一般情況下,lib文件里有相應的dll文件的名字和一個指明dll輸出函數入口的順序表。如果不想用lib文件或者是沒有lib文件,可以用WIN32 API函數LoadLibrary、GetProcAddress。事實上,我們可以在Visual C++ IDE中以二進制形式打開lib文件,大多情況下會看到ASCII碼格式的C++函數或一些重載操作的函數名字。
一般我們最主要的關于lib文件的麻煩就是出現unresolved symble 這類錯誤,這就是lib文件連接錯誤或者沒有包含.c、.cpp文件到工程里,關鍵是如果在C++工程里用了C語言寫的lib文件,就必需要這樣包含:
extern "C"
{
#include "myheader.h"
}
這是因為C語言寫的lib文件沒有C++所必須的名字破壞,C函數不能被重載,因此連接器會出錯。