Windows 編程瑣碎知識點

來源:互聯網
上載者:User

C語言時間函數
C語言的標準庫函數包括一系列日期和時間處理函數,它們都在標頭檔中說明。下面列出了這些函數。在標頭檔中定義了三種類型:time_t,struct tm和clock_t。

在中說明的C語言時間函數

time_t time(time_t *timer);

double difftime(time_t time1,time_t time2);

struct tm *gmtime(const time_t *timer);

struct tm *localtime(const time_t *timer);

char *asctime(const struct tm *timeptr);

char *ctime(const time_t *timer);

size_t strftime(char *s,size_t maxsize,const char *format,const struct tm *timeptr);

time_t mktime(struct tm *timeptr);

clock_t clock(void);

 

下面是我從網上收集到的時間函數集

 

 

asctime(將時間和日期以字串格式表示)
相關函數
time,ctime,gmtime,localtime
表標頭檔
#i nclude
定義函數
char * asctime(const struct tm * timeptr);
函數說明
asctime()將參數timeptr所指的tm結構中的資訊轉換成真實世界所使用的時間日期表示方法,然後將結果以字串形態返回。此函數已經由時區轉換成當地時間,字串格式為:"Wed Jun 30 21:49:08 1993/n"
傳回值
若再調用相關的時間日期函數,此字串可能會被破壞。此函數與ctime不同處在於傳入的參數是不同的結構。
附加說明
返回一字串表示目前當地的時間日期。
範例
#i nclude
main()
{
time_t timep;
time (&timep);
printf("%s",asctime(gmtime(&timep)));
}
執行
Sat Oct 28 02:10:06 2000
 

 

ctime(將時間和日期以字串格式表示)
相關函數
time,asctime,gmtime,localtime
表標頭檔
#i nclude
定義函數
char *ctime(const time_t *timep);
函數說明
ctime ()將參數timep所指的time_t結構中的資訊轉換成真實世界所使用的時間日期表示方法,然後將結果以字串形態返回。此函數已經由時區轉換成當地時間,字串格式為"Wed Jun 30 21 :49 :08 1993/n"。若再調用相關的時間日期函數,此字串可能會被破壞。
傳回值
返回一字串表示目前當地的時間日期。
範例
#i nclude
main()
{
time_t timep;
time (&timep);
printf("%s",ctime(&timep));
}
執行
Sat Oct 28 10 : 12 : 05 2000
 

 

gettimeofday(取得目前的時間)
相關函數
time,ctime,ftime,settimeofday
表標頭檔
#i nclude
#i nclude
定義函數
int gettimeofday ( struct timeval * tv , struct timezone * tz )
函數說明
gettimeofday()會把目前的時間有tv所指的結構返回,當地時區的資訊則放到tz所指的結構中。
timeval結構定義為:
struct timeval{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
timezone 結構定義為:
struct timezone{
int tz_minuteswest; /*和Greenwich 時間差了多少分鐘*/
int tz_dsttime; /*日光節約時間的狀態*/
};
上述兩個結構都定義在/usr/include/sys/time.h。tz_dsttime 所代表的狀態如下
DST_NONE /*不使用*/
DST_USA /*美國*/
DST_AUST /*澳洲*/
DST_WET /*西歐*/
DST_MET /*中歐*/
DST_EET /*東歐*/
DST_CAN /*加拿大*/
DST_GB /*大不列顛*/
DST_RUM /*羅馬尼亞*/
DST_TUR /*土耳其*/
DST_AUSTALT /*澳洲(1986年以後)*/
傳回值
成功則返回0,失敗返回-1,錯誤碼存於errno。附加說明EFAULT指標tv和tz所指的記憶體空間超出存取許可權。
範例
#i nclude
#i nclude
main(){
struct timeval tv;
struct timezone tz;
gettimeofday (&tv , &tz);
printf("tv_sec; %d/n", tv,.tv_sec) ;
printf("tv_usec; %d/n",tv.tv_usec);
printf("tz_minuteswest; %d/n", tz.tz_minuteswest);
printf("tz_dsttime, %d/n",tz.tz_dsttime);
}
執行
tv_sec: 974857339
tv_usec:136996
tz_minuteswest:-540
tz_dsttime:0
 

 

gmtime(取得目前時間和日期)
相關函數
time,asctime,ctime,localtime
表標頭檔
#i nclude
定義函數
struct tm*gmtime(const time_t*timep);
函數說明
gmtime()將參數timep 所指的time_t 結構中的資訊轉換成真實世界所使用的時間日期表示方法,然後將結果由結構tm返回。
結構tm的定義為
struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
int tm_sec 代表目前秒數,正常範圍為0-59,但允許至61秒
int tm_min 代表目前分數,範圍0-59
int tm_hour 從午夜算起的時數,範圍為0-23
int tm_mday 目前月份的日數,範圍01-31
int tm_mon 代表目前月份,從一月算起,範圍從0-11
int tm_year 從1900 年算起至今的年數
int tm_wday 一星期的日數,從星期一算起,範圍為0-6
int tm_yday 從今年1月1日算起至今的天數,範圍為0-365
int tm_isdst 日光節約時間的旗標
此函數返回的時間日期未經時區轉換,而是UTC時間。
傳回值
返回結構tm代表目前UTC 時間
範例
#i nclude
main(){
char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
time_t timep;
struct tm *p;
time(&timep);
p=gmtime(&timep);
printf("%d%d%d",(1900+p->tm_year), (1+p->tm_mon),p->tm_mday);
printf("%s%d;%d;%d/n", wday[p->tm_wday], p->tm_hour, p->tm_min, p->tm_sec);
}
執行
2000/10/28 Sat 8:15:38
 

 

localtime(取得當地目前時間和日期)
相關函數
time, asctime, ctime, gmtime
表標頭檔
#i nclude
定義函數
struct tm *localtime(const time_t * timep);
函數說明
localtime()將參數timep所指的time_t結構中的資訊轉換成真實世界所使用的時間日期表示方法,然後將結果由結構tm返回。結構tm的定義請參考gmtime()。此函數返回的時間日期已經轉換成當地時區。
傳回值
返回結構tm代表目前的當地時間。
範例
#i nclude
main(){
char *wday[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
time_t timep;
struct tm *p;
time(&timep);
p=localtime(&timep); /*取得當地時間*/
printf ("%d%d%d ", (1900+p->tm_year),( l+p->tm_mon), p->tm_mday);
printf("%s%d:%d:%d/n", wday[p->tm_wday],p->tm_hour, p->tm_min, p->tm_sec);
}
執行
2000/10/28 Sat 11:12:22
 

 

mktime(將時間結構資料轉換成經過的秒數)
相關函數
time,asctime,gmtime,localtime
表標頭檔
#i nclude
定義函數
time_t mktime(strcut tm * timeptr);
函數說明
mktime()用來將參數timeptr所指的tm結構資料轉換成從公元1970年1月1日0時0分0 秒算起至今的UTC時間所經過的秒數。
傳回值
返回經過的秒數。
範例
/* 用time()取得時間(秒數),利用localtime()
轉換成struct tm 再利用mktine()將struct tm轉換成原來的秒數*/
#i nclude
main()
{
time_t timep;
strcut tm *p;
time(&timep);
printf("time() : %d /n",timep);
p=localtime(&timep);
timep = mktime(p);
printf("time()->localtime()->mktime():%d/n",timep);
}
執行
time():974943297
time()->localtime()->mktime():974943297
 

 

settimeofday(設定目前時間)
相關函數
time,ctime,ftime,gettimeofday
表標頭檔
#i nclude
#i nclude
定義函數
int settimeofday ( const struct timeval *tv,const struct timezone *tz);
函數說明
settimeofday()會把目前時間設成由tv所指的結構資訊,當地時區資訊則設成tz所指的結構。詳細的說明請參考gettimeofday()。注意,只有root許可權才能使用此函數修改時間。
傳回值
成功則返回0,失敗返回-1,錯誤碼存於errno。
錯誤碼
EPERM 並非由root許可權調用settimeofday(),許可權不夠。
EINVAL 時區或某個資料是不正確的,無法正確設定時間。
 

 

time(取得目前的時間)
相關函數
ctime,ftime,gettimeofday
表標頭檔
#i nclude
定義函數
time_t time(time_t *t);
函數說明
此函數會返回從公元1970年1月1日的UTC時間從0時0分0秒算起到現在所經過的秒數。如果t 並非null 指標的話,此函數也會將傳回值存到t指標所指的記憶體。
傳回值
成功則返回秒數,失敗則返回((time_t)-1)值,錯誤原因存於errno中。
範例
#i nclude
mian()
{
int seconds= time((time_t*)NULL);
printf("%d/n",seconds);
}
執行
9.73E+08

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
VC視窗重新整理InvalidateRect和UpdateWindow RedrawWindow2010-01-12 17:43首先說說WM_PAINT 這個重要的訊息:

 
  The WM_PAINT message is generated by the system and should not be sent by an application.The system sends this message when there are no other messages in the application's message queue

  也就是說WM_PAINT訊息是由系統產生,非要等應用程式的訊息佇列為空白時才發送WM_PAINT訊息,並且 該訊息不應該被程式(自己寫代碼用SendMessage)來發送。

  當調用UpdateWindow函數,或者是Window檢測到 視窗被覆蓋的地方需要恢複的時候,比如,第一次建立視窗,改變了視窗的大小,最大化,最小化等等(其實這些事件發生時會調用UpdateWindow函 數,由該函數發送WM_PAINT訊息),它會向使用者程式發送一個WM_PAINT訊息。視窗過程收到WM_PAINT訊息後,並不代表整個客戶區都需要 被重新整理,有可能客戶區被覆蓋的地區只有一小塊,這個地區叫做“無效地區”,程式只需要更新這個地區。與WM_TIMER訊息類似,WM_PAINT訊息也 是一個低層級的訊息,雖然它不會像WM_TIMER訊息一樣被丟棄,但Windows總是在訊息迴圈空的時候才把WM_PAINT放入其中。

  無效地區的座標並不附帶在WM_PAINT訊息的參數中,在程式中有其他方法可以擷取。WM_PAINT訊息只 是通知程式有個地區需要更新而已,所以Windows也不會同時將兩條WM_PAINT訊息放入訊息迴圈中。當Windows要放入一條WM_PAINT 訊息的時候,如果發現已經存在一個無效地區了,那麼它只需要把新舊兩個無效地區合并計算出一個無效地區就可以了,訊息迴圈中還是只需要一條 WM_PAINT訊息。

  實際上,Windows為每個視窗維護一個“繪圖資訊結構”,無效地區的座標就在其中,每當訊息迴圈空的時候, 如果Windows發現存在一個無效地區,就會放入一個WM_PAINT訊息。那麼“繪圖資訊結構”怎麼擷取呢?BeginPaint函數的第二個參數就 是一個繪圖資訊結構的緩衝區地址,windows會在這裡返回繪圖資訊結構,結構中包含了無效地區的位置和大小,繪圖資訊結構的定義如下:

typedef struct tagPAINTSTRUCT { // ps 
HDC   hdc; 
BOOL fErase; 
RECT rcPaint; 
BOOL fRestore; 
BOOL fIncUpdate; 
BYTE rgbReserved[32]; 
} PAINTSTRUCT; 

  其中hdc欄位是視窗的裝置環境控制代碼,rcPaint欄位是一個RECT結構,它指定了無效地區矩形的對角頂點 (如果開始有一個((0,0),(40,40)),現在又來一個((20,20),(60,30)),那麼拼接後就是((0,0), (60,40))),fErase欄位如果為非零值,表示Windows在發送WM_PAINT訊息前已經使用背景色擦除了無效地區,後面3個欄位是 Windows內部使用的,應用程式不必去理會他們。

  在某些情況下,顯示地區的一部分被臨時覆蓋,Windows試圖 儲存一個顯示地區,並在以後恢複它,但這不一定能成功。Windows可能發送WM_PAINT訊息:Windows 擦除覆蓋了部分視窗的對話方塊或訊息框;菜單下拉出來,然後被釋放;顯示工具提示訊息。

  在某些情況下,Windows總是一定儲存它所覆蓋的顯示地區,然後恢複它。這些情況是:滑鼠游標穿越顯示地區;表徵圖拖過顯示地區。

  有時候應用也需要能夠主動引發視窗中的繪製操作,比如當視窗顯示的資料改變的時候,這一般是通過 InvalidateRect和 InvalidateRgn函數來完成的。InvalidateRect和InvalidateRgn把指定的地區加到視窗的Update Region中,當應用的訊息佇列沒有其他訊息時,如果視窗的Update Region不為空白時,系統就會自動產生WM_PAINT訊息。

  系統為什麼不在調用Invalidate時發送WM_PAINT訊息呢?又為什麼非要等應用訊息佇列為空白時才發 送WM_PAINT訊息呢?這是因為系統把在視窗中的繪製操作當作一種低優先順序的操作,於是盡 可能地推後做。不過這樣也有利於提高繪製的效率:兩個WM_PAINT訊息之間通過InvalidateRect和InvaliateRgn使之失效的區 域就會被累加起來,然後在一個WM_PAINT訊息中一次得到 更新,不僅能避免多次重複地更新同一地區,也最佳化了應用的更新操作。像這種通過InvalidateRect和InvalidateRgn來使視窗地區無 效,依賴於系統在合適的時機發送WM_PAINT訊息的機 制實際上是一種非同步工作方式,也就是說,在無效化視窗地區和發送WM_PAINT訊息之間是有延遲的;有時候這種延遲並不是我們希望的,這時我們當然可以 在無效化視窗地區後利用SendMessage 發送一條WM_PAINT訊息來強制立即重畫,但不如使用Windows GDI為我們提供的更方便和強大的函數:UpdateWindow和RedrawWindow。UpdateWindow會檢查視窗的Update Region,當其不為空白時才發送WM_PAINT訊息;RedrawWindow則給我們更多的控制:是否重畫非客戶區和背景,是否總是發送 WM_PAINT訊息而不管Update Region是否為空白等。

  BeginPaint

  今天在處理WM_PAINT訊息時產生了一個低級的錯誤,並搞的我花了快一個小時才找到原因。我在處理訊息時, 沒有使用BeginPaint和EndPaint這對函數,結果我其餘的訊息彈不出來,視窗拖動時,不停閃爍(其實那就是重繪)。後來還是在MSDN上找 到了答案,現將原話貼出來。(在MSDN的The WM_PAINT Message標題中)

  BeginPaint sets the update region of a window to NULL. This clears the region, preventing it fromgenerating subsequent WM_PAINT messages. If an application processes a WM_PAINT message but does not call BeginPaint or otherwise clear the update region, the application continues to receive WM_PAINT messages as long as the region is not empty. In all cases, an application must clear the update region before returning from the WM_PAINT message. 
BeginPaint函數的作用就是將視窗需要重繪的地區設定為空白(也就是Update Region置空)。在正常情況下,我們接收到了WM_PAINT訊息後,視窗的Update Region都是非空的(如果為空白就不需要發送WM_PAINT訊息了)。而當你響應這個訊息的時候又不調用BeginPaint來清空,視窗的 Update Region就一直是非空的,系統就會一直發送WM_PAINT訊息。這樣就形成了一個處理WM_PAINT訊息的死迴圈。

  BeginPaint和WM_PAINT訊息緊密相關。試一試在WM_PAINT處理函數中不寫 BeginPaint會怎樣?程式會像進入了一個死迴圈一樣達到驚人的CPU佔用率,你會發現程式總在處理一個接 一個的WM_PAINT訊息。這是因為在通常情況下,當應用收到WM_PAINT訊息時,視窗的Update Region都是非空的(如果為空白就不需要發送WM_PAINT訊息了),BeginPaint的一個作用就是把該Update Region置為空白,這樣如果不調用BeginPaint,視窗的Update Region就一直不為空白,如前所述,系統就會一直發送WM_PAINT訊息。

  BeginPaint和WM_ERASEBKGND訊息也有關係。當視窗的Update Region被標誌為需要擦除背景時,BeginPaint會發送WM_ERASEBKGND訊息來重畫背景,同時在其返回資訊裡有一個標誌表明視窗背景 是否被重畫過。當我們用InvalidateRect和InvalidateRgn來把指定地區加到Update Region中時,可以設定該地區是否需要被擦除背景,這樣下一個BeginPaint就知道是否需要發送WM_ERASEBKGND訊息了。

  當然關於 WM_PAINT訊息還有很多的知識需要學習。另外要注意的一點是,BeginPaint只能在WM_PAINT處理函數中使用,並且在調用了 BeginPaint函數後,不要忘記了調用EndPaint函數,他們可是一對的。

  重畫 函數 InvalidateRect,Invalidate,UpdateWindow, RedrawWindow

  InvalidateRect(部分地區) 和Invalidate(整個視窗) 僅僅是用來設定無效地區,但是並不重繪視窗。

  UpdateWindow 檢查視窗有無無效地區,如果有,則立即發送一個WM_PAINT 訊息給視窗並立即重畫。 

  RedrawWindow相當於先調用InvalidateRect,緊接著又調用UpdateWindow, 此外RedrawWindow還提供了一些前兩者沒法做到的功能。

      如果不調用 InvalidateRect就調用 UpdateWindow,那麼UpdateWindow什麼都不做,因為沒有無效地區。如果調用 InvalidateRect 後不調用UpdateWindow,則系統會自動在視窗訊息佇列為空白的時候,系統自動發送一WM_PAINT訊息。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
INT_PTR DialogBox(          HINSTANCE hInstance,
    LPCTSTR lpTemplate,
    HWND hWndParent,
    DLGPROC lpDialogFunc
);
這個函數根據對話方塊資源,建立一個強制回應對話方塊,這個對話方塊應該用EndDialog來結束。

hInstance 當前應用程式執行個體控制代碼。
lpTemplate 標識對話方塊模板資源,有兩種使用方式:一種是把對話方塊模板的ID強制轉為LPCTSTR,一種可以使用MAKEINTRESOURCE宏得到標識ID。
hWndParent 父視窗的控制代碼。
lpDialogFunc 對話方塊訊息處理函數。

HWND CreateDialog(          HINSTANCE hInstance,
    LPCTSTR lpTemplate,
    HWND hWndParent,
    DLGPROC lpDialogFunc
);
這個函數根據對話方塊資源,建立一個非強制回應對話方塊,這個對話方塊應該用DestroyWindow來結束。
函數的參數跟上面的DialogBox用法相同。

強制回應對話方塊一般是在棧中產生的,所以EndDialog可能只是隱藏視窗,並沒有銷毀,當強制回應對話方塊對應的對象離開生命區時即銷毀對話方塊。非強制回應對話方塊一般在堆中,所以要主動用DestroyWindow銷毀它。
DialogBox函數自己處理訊息迴圈(這個訊息迴圈在user32.dll裡面維護,看不到)且在對話方塊關閉後函數才會返回(傳回值是EndDialog的第二個參數,所以可以用EndDialog的第二個參數來標識子控制項的ID),而CreateDialog函數調用了CreateWindowEx函數來建立視窗並立即返回,之後這個視窗使用主視窗的訊息迴圈(即這個視窗產生的訊息可能直接發給這個視窗的處理函數,也可能進入主視窗的訊息迴圈)。

不管是模式的還是非強制回應對話方塊,對於不希望處理的訊息,都不應該調用DefWindowProc來處理(否則會有問題),因為系統會主動對這些訊息進行處理。對於不希望處理的訊息,程式要做的只是return FALSE即可,而對於處理過的訊息,則應該return TRUE。
這種情況跟主視窗的處理不同。主視窗對不希望處理的訊息也要調用DefWindowProc來處理,而每個訊息處理分支的傳回值是無關緊要的(不像對話方塊那樣一定要返回TRUE或FALSE那樣)。

非強制回應對話方塊跟主視窗使用同一個訊息迴圈,而因為非強制回應對話方塊的訊息會被系統主動調用這個對話方塊的處理函數來處理,所以在訊息迴圈中不應該再對這個訊息進行轉換和分發,可以把訊息迴圈改成這樣:
 // 主訊息迴圈:
 while (GetMessage(&msg, NULL, 0, 0))
 {
  if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
  {
   // 不是非強制回應對話方塊g_hFlashWnd的訊息才分發
   if ( !IsDialogMessage( g_hFlashWnd, &msg ) )
   {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
   }
  
  }
 }

CreateDialog會發出WM_INITDIALOG訊息。

一些例子代碼:
/// 非強制回應對話方塊訊息處理函數
BOOL __stdcall FlashWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
 switch ( msg )
 {
 case WM_INITDIALOG:
  break;
 
 case WM_PAINT:
  break;

 case WM_LBUTTONDOWN:
  DestroyWindow( hWnd );
  break;

 default:
  return FALSE;  // 沒處理過的訊息
 }

 return TRUE; // 處理過的
}

///建立一個非強制回應對話方塊
g_hFlashWnd  = CreateDialog( hInst, MAKEINTRESOURCE(IDD_FLASH), hWnd, (DLGPROC)FlashWndProc );
ShowWindow( g_hFlashWnd, SW_SHOW );

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/bluesky_03/archive/2008/05/06/2403233.aspx

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
一、建立的區別
在WIN32中,強制回應對話方塊的建立一般是使用DialogBox來進行建立的。而非強制回應對話方塊則是利用

CreateWindow來建立的。

在MFC或是WTL中,強制回應對話方塊一般是使用DoModal,而非強制回應對話方塊的建立則是使用Create。

強制回應對話方塊建立後,程式的其他視窗便不能進行操作,必須將該視窗關閉後,其他視窗才能進行操作。而

非強制回應對話方塊則無需這樣,它不強制要求使用者立即反應,而是與其他視窗同時接受使用者操作。

二、訊息響應的區別
在訊息回應程式面,強制回應對話方塊和非強制回應對話方塊之間又有著很大的區別。

強制回應對話方塊工作的時候,它有內部的訊息泵機制,控制項之間的互動不用我們人為的去控制,系統會協助我

們去處理。

非強制回應對話方塊則像普通視窗一樣,則由WinMain中書寫的訊息迴圈驅動。但由於是對話方塊,它對一些訊息

有特殊的處理。因此,在訊息迴圈中,需要先對對話方塊提供截獲訊息的機會。
While (GetMessage(&msg, NULL, 0, 0))
{
 if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))
 {
    TranslateMessage(&msg);
    DispatchMessage( &msg);
 }
}
如果當前取得的訊息是對話方塊的訊息,IsDialogMessage 將它交由對話訊息處理函數處理,並返回TRUE。

不需要再派發了。
注意:這個方法並不是很好用,因為當對話方塊過多的時候,處理起來就比較麻煩了。另一種處理的方法是

利用子類化控制項的方法,來處理控制項間的互動。

三、銷毀的區別
強制回應對話方塊的銷毀是使用EndDialog,而非強制回應對話方塊的銷毀是使用DestroyWindow.。所以我們在銷毀對

話框的時候,也要對其進行區別。

非強制回應對話方塊,使用者關閉對話方塊時,對話方塊訊息處理函數將收到WM_CLOSE訊息,接到後調用

DestroyWindow以銷毀非強制回應對話方塊。

強制回應對話方塊,則一般響應IDOK和IDCANCEL。在PPC上,我們對於OK鍵和X鍵的處理要注意這點。

四、其他

可見度:
非模態對話方塊的模板必須具有Visible風格,否則對話方塊將不可見,而模態對話方塊則無需設定該項風格。

更保險的辦法是調用ShowWindow(hDialog, SW_SHOW)來顯示對話方塊,而不管對話方塊是否具有Visible風格

。 

阻塞性:
Create在顯示了對話方塊後就立即返回,而DoModal是在對話方塊被關閉後才返回的。眾所周知,在MFC程式中

,視窗對象的生存期應長於對應的視窗,也就是說,不能在未關閉螢幕上視窗的情況下先把對應的視窗對

象刪除掉。由於在Create返回後,不能確定對話方塊是否已關閉,這樣也就無法確定對話方塊對象的生存期,

因此只好在堆中構建對話方塊對象,而不能以局部變數的形式來構建之。

 

 

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.