青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

用SkinMagic工具包創(chuàng)建換皮膚程序
作者:北京林業(yè)大學(xué) 李少杰

下載本文示例工程

代碼運(yùn)行效果圖如下:




以前看到瑞星和金山詞霸有換皮膚功能,很是羨慕,自己也想做個(gè)換皮膚的程序,但畢竟自己能力有限,以前在此處看到一篇介紹換皮膚功能的文章,但只能應(yīng)用在對(duì)話(huà)框程序上。我也試過(guò)像BCGCBar這樣的大型軟件,給我的感覺(jué)是軟件老是出問(wèn)題,應(yīng)用起來(lái)也很復(fù)雜。在年前我就看到本站有SkinMagic軟件包,但當(dāng)時(shí)不知怎么用,發(fā)了貼子也沒(méi)人回答。可能是很少有人用的緣故吧,本站也未更新此軟件包。偶然的一次機(jī)會(huì),讓我知道了怎樣來(lái)用它,
而且編譯出來(lái)的軟件體積很小,所以在這里向大家介紹一下,希望對(duì)大家有些幫助。
如何使用:
① 新建工程后,將SkinMagic包中的SkinMagicLib.h、SkinMagicLib.lib、DETOURS.lib拷貝到所在文件夾下,點(diǎn)擊Project->Add To Project->Files,包含到工程中。
② 在Resource View中點(diǎn)擊Import 菜單引入幾個(gè)Skin二進(jìn)制文件放在相同的“SKINMAGIC”文件夾下,分別給起一個(gè)名字(見(jiàn)源程序)。
③ 在stdafx.h中加入#include "SkinMagicLib.h"
④ 在此處添加如下內(nèi)容

if (!ProcessShellCommand(cmdInfo))
return FALSE;
/////////////////////////////////////////////////////////////////////////////////////////
VERIFY( 1 == InitSkinMagicLib( AfxGetInstanceHandle(), "Demo" ,NULL,NULL ) );//初始化類(lèi)庫(kù)
VERIFY( 1 == LoadSkinFromResource( AfxGetInstanceHandle()  , "KROMO" ,"SKINMAGIC") );//從資源中加載皮膚
VERIFY( 1 == SetWindowSkin( m_pMainWnd->m_hWnd , "MainFrame" ));
VERIFY( 1 == SetDialogSkin( "Dialog" ) );
((CMainFrame*)m_pMainWnd)->m_bSkinned = TRUE;
((CMainFrame*)m_pMainWnd)->m_nIndex = 0;
////////////////////////////////////////////////////////////////////////////////////////////
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
⑤ 在MainFrame中加入換皮膚菜單,及相應(yīng)的函數(shù),在函數(shù)中加載皮膚。
void CMainFrame::OnDevior()
{
LoadSkinFromResource( AfxGetInstanceHandle()  , "DEVIOR" ,"SKINMAGIC") ;
}
到此為止,完美的換皮膚程序就出來(lái)了。
posted @ 2009-05-21 09:32 wrh 閱讀(283) | 評(píng)論 (0)編輯 收藏

文章導(dǎo)讀:  [準(zhǔn)備工作]  1、將SkinMagicTrial.dll放置在調(diào)試目錄  2、設(shè)置庫(kù)文件目錄,在項(xiàng)目[連接器]的[附加依賴(lài)項(xiàng)]中加入庫(kù)SkinMagicTrial.lib  3、在項(xiàng)目的stdafx.h文件中加入頭文件 #include "SkinMagicLib.h"  [創(chuàng)建過(guò)程]  1、初始化SkinMagic庫(kù): 

  [準(zhǔn)備工作]

  1、將SkinMagicTrial.dll放置在調(diào)試目錄

  2、設(shè)置庫(kù)文件目錄,在項(xiàng)目[連接器]的[附加依賴(lài)項(xiàng)]中加入庫(kù)SkinMagicTrial.lib

  3、在項(xiàng)目的stdafx.h文件中加入頭文件 #include "SkinMagicLib.h"

  [創(chuàng)建過(guò)程]

  1、初始化SkinMagic庫(kù):

  要使用SkinMagic,這一步必不可少。在應(yīng)用程序類(lèi)的InitInstance()函數(shù)中行加入如下代碼(粗體部分):

  CWinApp::InitInstance();

  VERIFY( 1 == InitSkinMagicLib(AfxGetInstanceHandle(), NULL ,

  NULL, NULL ));

  說(shuō)明:

  int InitSkinMagicLib( //初始化SkinMagic工具庫(kù)
  HINSTANCE hInstance, //應(yīng)用程序句柄
  char* szApplication , //皮膚文件中定義的應(yīng)用程序名,置為NULL即可
  char* szRegCode, //SkinMagic的使用注冊(cè)碼。若無(wú)置為NULL
  char* szReserved2 //保留位,為NULL
  );

  2、調(diào)入皮膚文件:

  皮膚的調(diào)用有兩種方法,一是直接從皮膚文件中調(diào)用,另一種方法是從資源文件中調(diào)用,分別說(shuō)明如下:

  1)從皮膚文件中調(diào)用皮膚:緊接上句,加入如下代碼

  VERIFY( 1 == LoadSkinFile("corona.smf"));

  2)從資源文件中調(diào)用皮膚:

  VERIFY(1 == LoadSkinFromResource(NULL,"FUTURA","skin"));

  說(shuō)明:

int LoadSkinFromResource(
  HMODULE hModule, //包含皮膚文件的模塊句柄,若NULL表面在本模塊中
 char* lpSkinName , //皮膚資源的名稱(chēng)
  char* lpType); //資源的類(lèi)型

  3、為窗口添加皮膚:

  1)為標(biāo)準(zhǔn)窗口(擁有標(biāo)題欄、系統(tǒng)菜單、可變大小等特征,比如文檔/視圖結(jié)構(gòu)和有菜單的對(duì)話(huà)框)添加皮膚,通常用于主窗口。在應(yīng)用程序類(lèi)的InitInstance()函數(shù)的底部加入如下代碼:

  VERIFY( 1 == SetWindowSkin( m_pMainWnd->m_hWnd , "MainFrame" ));

  m_pMainWnd->ShowWindow(SW_SHOW);

  m_pMainWnd->UpdateWindow();

  說(shuō)明:

  int SetWindowSkin(
  HWND hWnd, //要使用皮膚的窗口句柄
  char* lpSkinName //為skinFrameWnd對(duì)象指定的名稱(chēng)
  );

  2)為對(duì)話(huà)框添加皮膚

  在對(duì)話(huà)框顯示之前調(diào)用,通常在應(yīng)用程序初始化函數(shù)中調(diào)用

  VERIFY( 1 == SetWindowSkin( m_pMainWnd->m_hWnd , "MainFrame" ));

  VERIFY( 1 == SetDialogSkin( "Dialog" ) );

  m_pMainWnd->ShowWindow(SW_SHOW);

  m_pMainWnd->UpdateWindow();

  說(shuō)明:

  int SetDialogSkin(
  char* lpSkinName //為skinFrameWnd對(duì)象指定的名稱(chēng)
  );
  使用該函數(shù)后,以后程序創(chuàng)建的對(duì)話(huà)框都將使用該皮膚,但對(duì)話(huà)框大小不可變。
3)為單個(gè)對(duì)話(huà)框窗口添加皮膚,例如在對(duì)話(huà)框視圖中:重載對(duì)話(huà)框視圖的創(chuàng)建函數(shù)OnCreate,加入如下代碼:

  VERIFY( 1 == SetSingleDialogSkin( m_hWnd, "Dialog" ) );

  EnableWindowScrollbarSkin( m_hWnd , SB_BOTH );

  說(shuō)明:

  int SetSingleDialogSkin(
  HWND hWnd, //要使用皮膚的窗口句柄
  char* lpSkinName //為skinFrameWnd對(duì)象指定的名稱(chēng)
  );
  int EnableWindowScrollbarSkin( //為滾動(dòng)條添加皮膚
  HWND hWnd, //要使用皮膚的窗口句柄
  int* fnBar //要使用皮膚的滾動(dòng)條,SB_BOTH表明是橫豎都是用皮膚
  );

  4、釋放SkinMagic資源
 
  重載應(yīng)用程序的ExitInstance()函數(shù),添加如下代碼:

  ExitSkinMagicLib();

posted @ 2009-05-20 20:57 wrh 閱讀(487) | 評(píng)論 (0)編輯 收藏
如果n <= 0,返回NULL
如果n == 1,返回"",也就是一個(gè)空串。
如果成功返回值等于string,也就是獲得的字符串的首地址。
如果出錯(cuò),或者讀到FILE的結(jié)尾,返回NULL.

以下是這個(gè)函數(shù)的實(shí)現(xiàn):

/***
*fgets.c - get string from a file
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines fgets() - read a string from a file
*
*******************************************************************************/

#include <cruntime.h>
#include <stdio.h>
#include <dbgint.h>
#include <file2.h>
#include <internal.h>
#include <mtdll.h>
#include <tchar.h>

/***
*char *fgets(string, count, stream) - input string from a stream
*
*Purpose:
* get a string, up to count-1 chars or '\n', whichever comes first,
* append '\0' and put the whole thing into string. the '\n' IS included
* in the string. if count<=1 no input is requested. if EOF is found
* immediately, return NULL. if EOF found after chars read, let EOF
* finish the string as '\n' would.
*
*Entry:
* char *string - pointer to place to store string
* int count - max characters to place at string (include \0)
* FILE *stream - stream to read from
*
*Exit:
* returns string with text read from file in it.
* if count <= 0 return NULL
* if count == 1 put null string in string
* returns NULL if error or end-of-file found immediately
*
*Exceptions:
*
*******************************************************************************/

_TSCHAR * __cdecl _fgetts (
_TSCHAR *string,
int count,
FILE *str
)
{
REG1 FILE *stream;
REG2 _TSCHAR *pointer = string;
_TSCHAR *retval = string;
int ch;

_VALIDATE_RETURN(( string != NULL ) || ( count == 0 ), EINVAL, NULL);
_VALIDATE_RETURN(( count >= 0 ), EINVAL, NULL);
_VALIDATE_RETURN(( str != NULL ), EINVAL, NULL);

if (count == 0)
{
return NULL;
}

/* The C Standard states the input buffer should remain
unchanged if EOF is encountered immediately. Hence we
do not blank out the input buffer here */

/* Init stream pointer */
stream = str;

_lock_str(stream);
__try {

#ifndef _UNICODE
_VALIDATE_STREAM_ANSI_SETRET(stream, EINVAL, retval, NULL);
#endif /* _UNICODE */
if(retval!=NULL)
{
while (--count)
{
if ((ch = _fgettc_nolock(stream)) == _TEOF)
{
if (pointer == string) {
retval=NULL;
goto done;
}

break;
}

if ((*pointer++ = (_TSCHAR)ch) == _T('\n'))
break;
}
*pointer = _T('\0');
}


/* Common return */
done:

; }
__finally {
_unlock_str(stream);
}

return(retval);
}
posted @ 2009-05-20 09:22 wrh 閱讀(779) | 評(píng)論 (0)編輯 收藏
F1: 幫助 
Ctrl+O :Open 
Ctrl+P :Print 
Ctrl+N :New 
Ctrl+Shift+F2 :清除所有書(shū)簽 
F2 :上一個(gè)書(shū)簽 
Shift+F2 :上一個(gè)書(shū)簽 
Alt+F2 :編輯書(shū)簽 
Ctrl+F2 :添加/刪除一個(gè)書(shū)簽 
F12 :Goto definition 
Shift+F12 :Goto reference 
Ctrl+'Num+' :Displays the next symbol definition or reference 
Ctrl+'Num-' :Displays the previous symbol definition or reference 
Ctrl+J/K :尋找上一個(gè)/下一個(gè)預(yù)編譯條件 
Ctrl+Shift+J/K :尋找上一個(gè)/下一個(gè)預(yù)編譯條件并將這一塊選定 
Ctrl+End :文檔尾 
Ctrl+Shift+End :選定從當(dāng)前位置到文檔尾 
Ctrl+Home :文檔頭 
Ctrl+Shift+Home :選定從當(dāng)前位置到文檔頭 
Ctrl+B/Alt+F9 :編輯斷點(diǎn) 
Alt+F3/Ctrl+F :查找 
F3 :查找下一個(gè) 
Shift+F3 :查找上一個(gè) 
Ctrl+]/Ctrl+E :尋找下一半括弧 
Ctrl+Shift+] :尋找下一半括弧并選定括弧之間的部分(包括括弧) 
Ctrl+Shift+E :尋找下一半括弧并選定括弧之間的部分(包括括弧) 
F4 :尋找下一個(gè)錯(cuò)誤/警告位置 
Shift+F4 :尋找上一個(gè)錯(cuò)誤/警告位置 
Shift+Home :選定從當(dāng)前位置到行首 
Shift+End :選定從當(dāng)前位置到行尾 
Ctrl+L :剪切當(dāng)前行 
Ctrl+Shift+L :刪除當(dāng)前行 
Alt+Shift+T :交換當(dāng)前行和上一行 
Ctrl+Alt+T :Brings up the completion list box 
Shift+PageDown :選定從當(dāng)前位置到下一頁(yè)當(dāng)前位置 
Shift+PageUp :選定從當(dāng)前位置到上一頁(yè)當(dāng)前位置 
Ctrl+Shift+Space:顯示函數(shù)參數(shù)的Tooltip 
Ctrl+Z/Alt+Backspace :Undo 
Ctrl+Shift+Z/Ctrl+Y :Redo 
F8 :當(dāng)前位置變成選定區(qū)域的頭/尾(再移動(dòng)光標(biāo)或者點(diǎn)鼠標(biāo)就會(huì)選定) 
Ctrl+Shift+F8 :當(dāng)前位置變成矩形選定區(qū)域的頭/尾(再移動(dòng)光標(biāo)或者點(diǎn)鼠標(biāo)就會(huì)選定) 
Alt+F8 :自動(dòng)格式重排 
Ctrl+G :Goto 
Ctlr+X/Shift+Del:Cut 
Ctrl+C/Ctrl+Ins :Copy 
Ctrl+V/Shift+Ins:Paste 
Ctrl+U :將選定區(qū)域轉(zhuǎn)換成小寫(xiě) 
Ctrl+Shift+U :將選定區(qū)域轉(zhuǎn)換成大寫(xiě) 
Ctrl+F8 :當(dāng)前行變成選定區(qū)域的頭/尾(再移動(dòng)上下光標(biāo)或者點(diǎn)鼠標(biāo)就會(huì)選定多行) 
Ctrl+Shift+L :刪除從當(dāng)前位置到行尾 
Ctrl+Shift+8 :將所有Tab變成`或者還原 
Ctrl+T :顯示變量類(lèi)型 
Ctrl+↑ :向上滾屏 
Ctrl+↓ :向下滾屏 
Ctrl+Del :刪除當(dāng)前單詞的后半截(以光標(biāo)為分割) 
Ctrl+Backspace :刪除當(dāng)前單詞的前半截(以光標(biāo)為分割) 
Ctrl+← :移到前一個(gè)單詞 
Ctrl+→ :移到后一個(gè)單詞 
Ctrl+Shift+← :選定當(dāng)前位置到前一個(gè)單詞 
Ctrl+Shift+→ :選定當(dāng)前位置到后一個(gè)單詞 
Ctrl+Shift+T :將本單詞和上一個(gè)單詞互換
posted @ 2009-04-24 15:48 wrh 閱讀(281) | 評(píng)論 (0)編輯 收藏
數(shù)學(xué)函數(shù),所在函數(shù)庫(kù)為math.h、stdlib.h、string.h、float.h    
  ----------------------------------------------------------------------------------------------------------  
   
   
  int   abs(int   i)   返回整型參數(shù)i的絕對(duì)值    
  double   cabs(struct   complex   znum)   返回復(fù)數(shù)znum的絕對(duì)值    
  double   fabs(double   x)   返回雙精度參數(shù)x的絕對(duì)值    
  long   labs(long   n)   返回長(zhǎng)整型參數(shù)n的絕對(duì)值    
  double   exp(double   x)   返回指數(shù)函數(shù)ex的值    
  double   frexp(double   value,int   *eptr)   返回value=x*2n中x的值,n存貯在eptr中    
  double   ldexp(double   value,int   exp);   返回value*2exp的值    
  double   log(double   x)   返回logex的值    
  double   log10(double   x)   返回log10x的值    
  double   pow(double   x,double   y)   返回xy的值    
  double   pow10(int   p)   返回10p的值    
  double   sqrt(double   x)   返回x的開(kāi)方    
  double   acos(double   x)   返回x的反余弦cos-1(x)值,x為弧度    
  double   asin(double   x)   返回x的反正弦sin-1(x)值,x為弧度    
  double   atan(double   x)   返回x的反正切tan-1(x)值,x為弧度    
  double   atan2(double   y,double   x)   返回y/x的反正切tan-1(x)值,y的x為弧度    
  double   cos(double   x)   返回x的余弦cos(x)值,x為弧度    
  double   sin(double   x)   返回x的正弦sin(x)值,x為弧度    
  double   tan(double   x)   返回x的正切tan(x)值,x為弧度    
  double   cosh(double   x)   返回x的雙曲余弦cosh(x)值,x為弧度    
  double   sinh(double   x)   返回x的雙曲正弦sinh(x)值,x為弧度    
  double   tanh(double   x)   返回x的雙曲正切tanh(x)值,x為弧度    
  double   hypot(double   x,double   y)   返回直角三角形斜邊的長(zhǎng)度(z),   x和y為直角邊的長(zhǎng)度,z2=x2+y2    
  double   ceil(double   x)   返回不小于x的最小整數(shù)    
  double   floor(double   x)   返回不大于x的最大整數(shù)    
  void   srand(unsigned   seed)   初始化隨機(jī)數(shù)發(fā)生器    
  int   rand()   產(chǎn)生一個(gè)隨機(jī)數(shù)并返回這個(gè)數(shù)    
  double   poly(double   x,int   n,double   c[])   從參數(shù)產(chǎn)生一個(gè)多項(xiàng)式    
  double   modf(double   value,double   *iptr)   將雙精度數(shù)value分解成尾數(shù)和階    
  double   fmod(double   x,double   y)   返回x/y的余數(shù)    
  double   frexp(double   value,int   *eptr)   將雙精度數(shù)value分成尾數(shù)和階    
  double   atof(char   *nptr)   將字符串nptr轉(zhuǎn)換成浮點(diǎn)數(shù)并返回這個(gè)浮點(diǎn)數(shù)    
  double   atoi(char   *nptr)   將字符串nptr轉(zhuǎn)換成整數(shù)并返回這個(gè)整數(shù)    
  double   atol(char   *nptr)   將字符串nptr轉(zhuǎn)換成長(zhǎng)整數(shù)并返回這個(gè)整數(shù)    
  char   *ecvt(double   value,int   ndigit,int   *decpt,int   *sign)    
  將浮點(diǎn)數(shù)value轉(zhuǎn)換成字符串并返回該字符串    
  char   *fcvt(double   value,int   ndigit,int   *decpt,int   *sign)    
  將浮點(diǎn)數(shù)value轉(zhuǎn)換成字符串并返回該字符串    
  char   *gcvt(double   value,int   ndigit,char   *buf)    
  將數(shù)value轉(zhuǎn)換成字符串并存于buf中,并返回buf的指針    
  char   *ultoa(unsigned   long   value,char   *string,int   radix)    
  將無(wú)符號(hào)整型數(shù)value轉(zhuǎn)換成字符串并返回該字符串,radix為轉(zhuǎn)換時(shí)所用基數(shù)    
  char   *ltoa(long   value,char   *string,int   radix)    
  將長(zhǎng)整型數(shù)value轉(zhuǎn)換成字符串并返回該字符串,radix為轉(zhuǎn)換時(shí)所用基數(shù)    
  char   *itoa(int   value,char   *string,int   radix)    
  將整數(shù)value轉(zhuǎn)換成字符串存入string,radix為轉(zhuǎn)換時(shí)所用基數(shù)    
  double   atof(char   *nptr)   將字符串nptr轉(zhuǎn)換成雙精度數(shù),并返回這個(gè)數(shù),錯(cuò)誤返回0    
  int   atoi(char   *nptr)   將字符串nptr轉(zhuǎn)換成整型數(shù),   并返回這個(gè)數(shù),錯(cuò)誤返回0    
  long   atol(char   *nptr)   將字符串nptr轉(zhuǎn)換成長(zhǎng)整型數(shù),并返回這個(gè)數(shù),錯(cuò)誤返回0    
  double   strtod(char   *str,char   **endptr)將字符串str轉(zhuǎn)換成雙精度數(shù),并返回這個(gè)數(shù),    
  long   strtol(char   *str,char   **endptr,int   base)將字符串str轉(zhuǎn)換成長(zhǎng)整型數(shù),   并返回這個(gè)數(shù),    
  int   matherr(struct   exception   *e)   用戶(hù)修改數(shù)學(xué)錯(cuò)誤返回信息函數(shù)(沒(méi)有必要使用)    
  double   _matherr(_mexcep   why,char   *fun,double   *arg1p,   double   *arg2p,double   retval)    
  用戶(hù)修改數(shù)學(xué)錯(cuò)誤返回信息函數(shù)(沒(méi)有必要使用)    
  unsigned   int   _clear87()   清除浮點(diǎn)狀態(tài)字并返回原來(lái)的浮點(diǎn)狀態(tài)    
  void   _fpreset()   重新初使化浮點(diǎn)數(shù)學(xué)程序包    
  unsigned   int   _status87()   返回浮點(diǎn)狀態(tài)字
posted @ 2009-04-15 10:03 wrh 閱讀(524) | 評(píng)論 (0)編輯 收藏

在VC++6.0中missing function header (old-style formal list?)解決方法

該函數(shù)的函數(shù)頭后邊加了分號(hào)

去掉即可

例如:void fun();{}就會(huì)出現(xiàn)那種情況

posted @ 2009-03-27 10:37 wrh 閱讀(2070) | 評(píng)論 (0)編輯 收藏

VC中沒(méi)有現(xiàn)成的函數(shù)來(lái)選擇一個(gè)文件夾,但這是經(jīng)常會(huì)用到的,怎么辦?
自動(dòng)動(dòng)手,豐衣足食!

使用SHBrowseForFolder,代碼如下:

#include
  
int SelFolder(HWND hParent, CString &strFolder)
{
    strFolder.Empty();
 
    LPMALLOC lpMalloc;
 
    if (::SHGetMalloc(&lpMalloc) != NOERROR) return 0;
 
    char szDisplayName[_MAX_PATH];
    char szBuffer[_MAX_PATH];
    BROWSEINFO browseInfo;
    browseInfo.hwndOwner = hParent;
    browseInfo.pidlRoot = NULL; // set root at Desktop
    browseInfo.pszDisplayName = szDisplayName;
    browseInfo.lpszTitle = "Select a folder";
    browseInfo.ulFlags = BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;
    browseInfo.lpfn = NULL;
    browseInfo.lParam = 0;
 
    LPITEMIDLIST lpItemIDList;
    if ((lpItemIDList = ::SHBrowseForFolder(&browseInfo)) != NULL)
    {
        // Get the path of the selected folder from the    item ID list.
        if (::SHGetPathFromIDList(lpItemIDList, szBuffer))
        {
            // At this point, szBuffer contains the path the user chose.
            if (szBuffer[0] == ´\0´) return 0;
 
            // We have a path in szBuffer! Return it.
            strFolder = szBuffer;
            return 1;
        }
        else return 1; // strResult is empty
 
        lpMalloc->Free(lpItemIDList);
        lpMalloc->Release();
    }
   
 return 1;
}

 

//////調(diào)用:

void CMusic1Dlg::OnOK()
{
 // TODO: Add extra validation here
 CString str;

 HWND m_hWnd = GetSafeHwnd();
 
 SelFolder(m_hWnd,str);

 m_list.AddString(str);
// CDialog::OnOK();
}

//------------------------------------------------------------------------------------------------------

//_________________________________________________________________

“選擇文件夾”對(duì)話(huà)框的封裝


我們經(jīng)常需要用到“選擇文件夾”對(duì)話(huà)框,相應(yīng)的API已經(jīng)很好用,但稍嫌麻煩,所以我專(zhuān)門(mén)將其封裝了一下,力求一步到位。

函數(shù)封裝如下:
/*****************************************************************
** 函數(shù)名:GetPath
** 輸 入: 無(wú)
** 輸 出: CString strPath
**        strPath非空, 表示用戶(hù)選擇的文件夾路徑
**        strPath為空, 表示用戶(hù)點(diǎn)擊了“取消”鍵,取消選擇
** 功能描述:顯示“選擇文件夾”對(duì)話(huà)框,讓用戶(hù)選擇文件夾
****************************************************************/

CString GetPath()
{
 CString strPath = "";
 BROWSEINFO bInfo;
 ZeroMemory(&bInfo, sizeof(bInfo));
 bInfo.hwndOwner = m_hWnd;
 bInfo.lpszTitle = _T("請(qǐng)選擇路徑: ");
 bInfo.ulFlags = BIF_RETURNONLYFSDIRS;   
 
 LPITEMIDLIST lpDlist; //用來(lái)保存返回信息的IDList
 lpDlist = SHBrowseForFolder(&bInfo) ; //顯示選擇對(duì)話(huà)框
 if(lpDlist != NULL)  //用戶(hù)按了確定按鈕
 {
  TCHAR chPath[255]; //用來(lái)存儲(chǔ)路徑的字符串
  SHGetPathFromIDList(lpDlist, chPath);//把項(xiàng)目標(biāo)識(shí)列表轉(zhuǎn)化成字符串
  strPath = chPath; //將TCHAR類(lèi)型的字符串轉(zhuǎn)換為CString類(lèi)型的字符串
 }
 return strPath;
}

調(diào)用時(shí)只需要用到以下代碼:
CString strPath = GetPath();
則strPath為用戶(hù)選擇的文件夾路徑。如果用戶(hù)點(diǎn)擊了對(duì)話(huà)框的取消鍵,則strPath為空字符串("");

posted @ 2009-03-14 10:02 wrh 閱讀(5249) | 評(píng)論 (1)編輯 收藏
char   path[MAX_PATH];  
  GetModuleFileName(NULL,path,MAX_PATH);

GetModuleFileName(   AfxGetInstanceHandle(),szPath,MAX_PATH);


GetModuleFileNameEx  
  The   GetModuleFileNameEx   function   retrieves   the   fully   qualified   path   for   the   specified   module.    
   
  DWORD   GetModuleFileNameEx(  
      HANDLE   hProcess,         //   handle   to   the   process  
      HMODULE   hModule,         //   handle   to   the   module  
      LPTSTR   lpFilename,     //   buffer   that   receives   the   path  
      DWORD   nSize                   //   size   of   the   buffer  
  );  
     
  Parameters  
  hProcess    
  Handle   to   the   process   that   contains   the   module.    
  hModule    
  Handle   to   the   module.    
  lpFilename    
  Pointer   to   the   buffer   that   receives   the   fully   qualified   path   to   the   module.    
  nSize    
  Specifies   the   size,   in   bytes,   of   the   lpFilename   buffer.    
  Return   Value  
  If   the   function   succeeds,   the   return   value   specifies   the   length   of   the   string   copied   to   the   buffer.    
   
  If   the   function   fails,   the   return   value   is   zero.   To   get   extended   error   information,   call   GetLastError.    
   
  See   Also  
  Process   Status   Helper   Overview,   PSAPI   Functions,   EnumProcesses,   GetModuleBaseName     
   
posted @ 2009-03-14 10:00 wrh 閱讀(1499) | 評(píng)論 (0)編輯 收藏

文件的打開(kāi)(fopen函數(shù))

fopen函數(shù)用來(lái)打開(kāi)一個(gè)文件,其調(diào)用的一般形式為:
文件指針名=fopen(文件名,使用文件方式);
其中,
“文件指針名”必須是被說(shuō)明為FILE 類(lèi)型的指針變量;
“文件名”是被打開(kāi)文件的文件名;
“使用文件方式”是指文件的類(lèi)型和操作要求。
“文件名”是字符串常量或字符串?dāng)?shù)組。
例如:
FILE *fp;
fp=("file a","r");
其意義是在當(dāng)前目錄下打開(kāi)文件file a,只允許進(jìn)行“讀”操作,并使fp指向該文件。
又如:
FILE *fphzk
fphzk=("c:\\hzk16","rb")
其意義是打開(kāi)C驅(qū)動(dòng)器磁盤(pán)的根目錄下的文件hzk16,這是一個(gè)二進(jìn)制文件,只允許按二進(jìn)制方式進(jìn)行讀操作。兩個(gè)反斜線(xiàn)“\\ ”中的第一個(gè)表示轉(zhuǎn)義字符,第二個(gè)表示根目錄。

使用文件的方式共有12種,下面給出了它們的符號(hào)和意義。
文件使用方式 意義
“rt” 只讀打開(kāi)一個(gè)文本文件,只允許讀數(shù)據(jù)
“wt” 只寫(xiě)打開(kāi)或建立一個(gè)文本文件,只允許寫(xiě)數(shù)據(jù)
“at” 追加打開(kāi)一個(gè)文本文件,并在文件末尾寫(xiě)數(shù)據(jù)
“rb” 只讀打開(kāi)一個(gè)二進(jìn)制文件,只允許讀數(shù)據(jù)
“wb” 只寫(xiě)打開(kāi)或建立一個(gè)二進(jìn)制文件,只允許寫(xiě)數(shù)據(jù)
“ab” 追加打開(kāi)一個(gè)二進(jìn)制文件,并在文件末尾寫(xiě)數(shù)據(jù)
“rt+” 讀寫(xiě)打開(kāi)一個(gè)文本文件,允許讀和寫(xiě)
“wt+” 讀寫(xiě)打開(kāi)或建立一個(gè)文本文件,允許讀寫(xiě)
“at+” 讀寫(xiě)打開(kāi)一個(gè)文本文件,允許讀,或在文件末追加數(shù)據(jù)
“rb+” 讀寫(xiě)打開(kāi)一個(gè)二進(jìn)制文件,允許讀和寫(xiě)
“wb+” 讀寫(xiě)打開(kāi)或建立一個(gè)二進(jìn)制文件,允許讀和寫(xiě)
“ab+” 讀寫(xiě)打開(kāi)一個(gè)二進(jìn)制文件,允許讀,或在文件末追加數(shù)據(jù)

對(duì)于文件使用方式有以下幾點(diǎn)說(shuō)明:
1) 文件使用方式由r,w,a,t,b,+六個(gè)字符拼成,各字符的含義是:
r(read): 讀
w(write): 寫(xiě)
a(append): 追加
t(text): 文本文件,可省略不寫(xiě)
b(banary): 二進(jìn)制文件
+: 讀和寫(xiě)
2) 凡用“r”打開(kāi)一個(gè)文件時(shí),該文件必須已經(jīng)存在,且只能從該文件讀出。
3) 用“w”打開(kāi)的文件只能向該文件寫(xiě)入。若打開(kāi)的文件不存在,則以指定的文件名建立該文件,若打開(kāi)的文件已經(jīng)存在,則將該文件刪去,重建一個(gè)新文件。
4) 若要向一個(gè)已存在的文件追加新的信息,只能用“a”方式打開(kāi)文件。但此時(shí)該文件必須是存在的,否則將會(huì)出錯(cuò)。
5) 在打開(kāi)一個(gè)文件時(shí),如果出錯(cuò),fopen將返回一個(gè)空指針值NULL。在程序中可以用這一信息來(lái)判別是否完成打開(kāi)文件的工作,并作相應(yīng)的處理。因此常用以下程序段打開(kāi)文件:
6) if((fp=fopen("c:\\hzk16","rb")==NULL)
{
printf("\nerror on open c:\\hzk16 file!");
getch();
exit(1);
}

這段程序的意義是,如果返回的指針為空,表示不能打開(kāi)C盤(pán)根目錄下的hzk16文件,則給出提示信息“error on open c:\ hzk16 file!”,下一行g(shù)etch()的功能是從鍵盤(pán)輸入一個(gè)字符,但不在屏幕上顯示。在這里,該行的作用是等待,只有當(dāng)用戶(hù)從鍵盤(pán)敲任一鍵時(shí),程序才繼續(xù)執(zhí)行,因此用戶(hù)可利用這個(gè)等待時(shí)間閱讀出錯(cuò)提示。敲鍵后執(zhí)行exit(1)退出程序。

7) 把一個(gè)文本文件讀入內(nèi)存時(shí),要將ASCII碼轉(zhuǎn)換成二進(jìn)制碼,而把文件以文本方式寫(xiě)入磁盤(pán)時(shí),也要把二進(jìn)制碼轉(zhuǎn)換成ASCII碼,因此文本文件的讀寫(xiě)要花費(fèi)較多的轉(zhuǎn)換時(shí)間。對(duì)二進(jìn)制文件的讀寫(xiě)不存在這種轉(zhuǎn)換。

8) 標(biāo)準(zhǔn)輸入文件(鍵盤(pán)),標(biāo)準(zhǔn)輸出文件(顯示器),標(biāo)準(zhǔn)出錯(cuò)輸出(出錯(cuò)信息)是由系統(tǒng)打開(kāi)的,可直接使用。

posted @ 2009-03-13 13:08 wrh 閱讀(9388) | 評(píng)論 (0)編輯 收藏
隊(duì)列消息和非隊(duì)列消息
   
從消息的發(fā)送途徑來(lái)看,消息可以分成2種:隊(duì)列消息和非隊(duì)列消息。消息隊(duì)列由可以分成系統(tǒng)消息隊(duì)列和線(xiàn)程消息隊(duì)列。系統(tǒng)消息隊(duì)列由Windows維護(hù),線(xiàn)程消息隊(duì)列則由每個(gè)GUI線(xiàn)程自己進(jìn)行維護(hù),為避免給non-GUI現(xiàn)成創(chuàng)建消息隊(duì)列,所有線(xiàn)程產(chǎn)生時(shí)并沒(méi)有消息隊(duì)列,僅當(dāng)線(xiàn)程第一次調(diào)用GDI函數(shù)數(shù)系統(tǒng)給線(xiàn)程創(chuàng)建一個(gè)消息隊(duì)列。隊(duì)列消息送到系統(tǒng)消息隊(duì)列,然后到線(xiàn)程消息隊(duì)列;非隊(duì)列消息直接送給目的窗口過(guò)程。
     對(duì)于隊(duì)列消息,最常見(jiàn)的是鼠標(biāo)和鍵盤(pán)觸發(fā)的消息,例如WM_MOUSERMOVE,WM_CHAR等消息,還有一些其它的消息,例如:WM_PAINT、WM_TIMER和WM_QUIT。當(dāng)鼠標(biāo)、鍵盤(pán)事件被觸發(fā)后,相應(yīng)的鼠標(biāo)或鍵盤(pán)驅(qū)動(dòng)程序就會(huì)把這些事件轉(zhuǎn)換成相應(yīng)的消息,然后輸送到系統(tǒng)消息隊(duì)列,由Windows系統(tǒng)去進(jìn)行處理。Windows系統(tǒng)則在適當(dāng)?shù)臅r(shí)機(jī),從系統(tǒng)消息隊(duì)列中取出一個(gè)消息,根據(jù)前面我們所說(shuō)的MSG消息結(jié)構(gòu)確定消息是要被送往那個(gè)窗口,然后把取出的消息送往創(chuàng)建窗口的線(xiàn)程的相應(yīng)隊(duì)列,下面的事情就該由線(xiàn)程消息隊(duì)列操心了,Windows開(kāi)始忙自己的事情去了。線(xiàn)程看到自己的消息隊(duì)列中有消息,就從隊(duì)列中取出來(lái),通過(guò)操作系統(tǒng)發(fā)送到合適的窗口過(guò)程去處理。
     一般來(lái)講,系統(tǒng)總是將消息Post在消息隊(duì)列的末尾。這樣保證窗口以先進(jìn)先出的順序接受消息。然而,WM_PAINT是一個(gè)例外,同一個(gè)窗口的多個(gè) WM_PAINT被合并成一個(gè) WM_PAINT 消息, 合并所有的無(wú)效區(qū)域到一個(gè)無(wú)效區(qū)域。合并WM_PAIN的目的是為了減少刷新窗口的次數(shù)。
    非隊(duì)列消息將會(huì)繞過(guò)系統(tǒng)隊(duì)列和消息隊(duì)列,直接將消息發(fā)送到窗口過(guò)程,。系統(tǒng)發(fā)送非隊(duì)列消息通知窗口,系統(tǒng)發(fā)送消息通知窗口。 例如,當(dāng)用戶(hù)激活一個(gè)窗口系統(tǒng)發(fā)送WM_ACTIVATE, WM_SETFOCUS, and WM_SETCURSOR。這些消息通知窗口它被激活了。非隊(duì)列消息也可以由當(dāng)應(yīng)用程序調(diào)用系統(tǒng)函數(shù)產(chǎn)生。例如,當(dāng)程序調(diào)用SetWindowPos系統(tǒng)發(fā)送WM_WINDOWPOSCHANGED消息。一些函數(shù)也發(fā)送非隊(duì)列消息,例如下面我們要談到的函數(shù)。
    
消息的發(fā)送
     了解了上面的這些基礎(chǔ)理論之后,我們就可以進(jìn)行一下簡(jiǎn)單的消息發(fā)送與接收。
     把一個(gè)消息發(fā)送到窗口有3種方式:發(fā)送、寄送和廣播。
     發(fā)送消息的函數(shù)有SendMessage、SendMessageCallback、SendNotifyMessage、SendMessageTimeout;寄送消息的函數(shù)主要有PostMessage、PostThreadMessage、PostQuitMessage;廣播消息的函數(shù)我知道的只有BroadcastSystemMessage、BroadcastSystemMessageEx。
     SendMessage的原型如下:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),這個(gè)函數(shù)主要是向一個(gè)或多個(gè)窗口發(fā)送一條消息,一直等到消息被處理之后才會(huì)返回。不過(guò)需要注意的是,如果接收消息的窗口是同一個(gè)應(yīng)用程序的一部分,那么這個(gè)窗口的窗口函數(shù)就被作為一個(gè)子程序馬上被調(diào)用;如果接收消息的窗口是被另外的線(xiàn)程所創(chuàng)建的,那么窗口系統(tǒng)就切換到相應(yīng)的線(xiàn)程并且調(diào)用相應(yīng)的窗口函數(shù),這條消息不會(huì)被放進(jìn)目標(biāo)應(yīng)用程序隊(duì)列中。函數(shù)的返回值是由接收消息的窗口的窗口函數(shù)返回,返回的值取決于被發(fā)送的消息。
     PostMessage的原型如下:BOOL PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam),該函數(shù)把一條消息放置到創(chuàng)建hWnd窗口的線(xiàn)程的消息隊(duì)列中,該函數(shù)不等消息被處理就馬上將控制返回。需要注意的是,如果hWnd參數(shù)為HWND_BROADCAST,那么,消息將被寄送給系統(tǒng)中的所有的重疊窗口和彈出窗口,但是子窗口不會(huì)收到該消息;如果hWnd參數(shù)為NULL,則該函數(shù)類(lèi)似于將dwThreadID參數(shù)設(shè)置成當(dāng)前線(xiàn)程的標(biāo)志來(lái)調(diào)用PostThreadMEssage函數(shù)。
  從上面的這2個(gè)具有代表性的函數(shù),我們可以看出消息的發(fā)送方式和寄送方式的區(qū)別所在:被發(fā)送的消息是否會(huì)被立即處理,函數(shù)是否立即返回。被發(fā)送的消息會(huì)被立即處理,處理完畢后函數(shù)才會(huì)返回;被寄送的消息不會(huì)被立即處理,他被放到一個(gè)先進(jìn)先出的隊(duì)列中,一直等到應(yīng)用程序空線(xiàn)的時(shí)候才會(huì)被處理,不過(guò)函數(shù)放置消息后立即返回。
  實(shí)際上,發(fā)送消息到一個(gè)窗口處理過(guò)程和直接調(diào)用窗口處理過(guò)程之間并沒(méi)有太大的區(qū)別,他們直接的唯一區(qū)別就在于你可以要求操作系統(tǒng)截獲所有被發(fā)送的消息,但是不能夠截獲對(duì)窗口處理過(guò)程的直接調(diào)用。
  以寄送方式發(fā)送的消息通常是與用戶(hù)輸入事件相對(duì)應(yīng)的,因?yàn)檫@些事件不是十分緊迫,可以進(jìn)行緩慢的緩沖處理,例如鼠標(biāo)、鍵盤(pán)消息會(huì)被寄送,而按鈕等消息則會(huì)被發(fā)送。
  廣播消息用得比較少,BroadcastSystemMessage函數(shù)原型如下:
      long BroadcastSystemMessage(DWORD dwFlags,LPDWORD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam);該函數(shù)可以向指定的接收者發(fā)送一條消息,這些接收者可以是應(yīng)用程序、可安裝的驅(qū)動(dòng)程序、網(wǎng)絡(luò)驅(qū)動(dòng)程序、系統(tǒng)級(jí)別的設(shè)備驅(qū)動(dòng)消息和他們的任意組合。需要注意的是,如果dwFlags參數(shù)是BSF_QUERY并且至少一個(gè)接收者返回了BROADCAST_QUERY_DENY,則返回值為0,如果沒(méi)有指定BSF_QUERY,則函數(shù)將消息發(fā)送給所有接收者,并且忽略其返回值。

消息的接收
 
消息的接收主要有3個(gè)函數(shù):GetMessage、PeekMessage、WaitMessage。
  GetMessage原型如下:BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax);該函數(shù)用來(lái)獲取與hWnd參數(shù)所指定的窗口相關(guān)的且wMsgFilterMin和wMsgFilterMax參數(shù)所給出的消息值范圍內(nèi)的消息。需要注意的是,如果hWnd為NULL,則GetMessage獲取屬于調(diào)用該函數(shù)應(yīng)用程序的任一窗口的消息,如果wMsgFilterMin和wMsgFilterMax都是0,則GetMessage就返回所有可得到的消息。函數(shù)獲取之后將刪除消息隊(duì)列中的除WM_PAINT消息之外的其他消息,至于WM_PAINT則只有在其處理之后才被刪除。
   PeekMessage原型如下:BOOL PeekMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax,UINT wRemoveMsg);該函數(shù)用于查看應(yīng)用程序的消息隊(duì)列,如果其中有消息就將其放入lpMsg所指的結(jié)構(gòu)中,不過(guò),與GetMessage不同的是,PeekMessage函數(shù)不會(huì)等到有消息放入隊(duì)列時(shí)才返回。同樣,如果hWnd為NULL,則PeekMessage獲取屬于調(diào)用該函數(shù)應(yīng)用程序的任一窗口的消息,如果hWnd=-1,那么函數(shù)只返回把hWnd參數(shù)為NULL的PostAppMessage函數(shù)送去的消息。如果wMsgFilterMin和wMsgFilterMax都是0,則PeekMessage就返回所有可得到的消息。函數(shù)獲取之后將刪除消息隊(duì)列中的除WM_PAINT消息之外的其他消息,至于WM_PAINT則只有在其處理之后才被刪除。
   WaitMessage原型如下:BOOL VaitMessage();當(dāng)一個(gè)應(yīng)用程序無(wú)事可做時(shí),該函數(shù)就將控制權(quán)交給另外的應(yīng)用程序,同時(shí)將該應(yīng)用程序掛起,直到一個(gè)新的消息被放入應(yīng)用程序的隊(duì)列之中才返回。

消息的處理
  接下來(lái)我們談一下消息的處理,首先我們來(lái)看一下VC中的消息泵:
while(GetMessage(&msg, NULL, 0, 0))
{
       if(!TranslateAccelerator(msg.hWnd, hAccelTable, &msg))
      {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
       }
}

   首先,GetMessage從進(jìn)程的主線(xiàn)程的消息隊(duì)列中獲取一個(gè)消息并將它復(fù)制到MSG結(jié)構(gòu),如果隊(duì)列中沒(méi)有消息,則GetMessage函數(shù)將等待一個(gè)消息的到來(lái)以后才返回。 如果你將一個(gè)窗口句柄作為第二個(gè)參數(shù)傳入GetMessage,那么只有指定窗口的的消息可以從隊(duì)列中獲得。GetMessage也可以從消息隊(duì)列中過(guò)濾消息只接受消息隊(duì)列中落在范圍內(nèi)的消息。這時(shí)候就要利用GetMessage/PeekMessage指定一個(gè)消息過(guò)濾器。這個(gè)過(guò)濾器是一個(gè)消息標(biāo)識(shí)符的范圍或者是一個(gè)窗體句柄,或者兩者同時(shí)指定。當(dāng)應(yīng)用程序要查找一個(gè)后入消息隊(duì)列的消息是很有用。WM_KEYFIRST 和 WM_KEYLAST 常量用于接受所有的鍵盤(pán)消息。 WM_MOUSEFIRST 和 WM_MOUSELAST 常量用于接受所有的鼠標(biāo)消息。
 然后TranslateAccelerator判斷該消息是不是一個(gè)按鍵消息并且是一個(gè)加速鍵消息,如果是,則該函數(shù)將把幾個(gè)按鍵消息轉(zhuǎn)換成一個(gè)加速鍵消息傳遞給窗口的回調(diào)函數(shù)。處理了加速鍵之后,函數(shù)TranslateMessage將把兩個(gè)按鍵消息WM_KEYDOWN和WM_KEYUP轉(zhuǎn)換成一個(gè)WM_CHAR,不過(guò)需要注意的是,消息WM_KEYDOWN,WM_KEYUP仍然將傳遞給窗口的回調(diào)函數(shù)。    
 處理完之后,DispatchMessage函數(shù)將把此消息發(fā)送給該消息指定的窗口中已設(shè)定的回調(diào)函數(shù)。如果消息是WM_QUIT,則GetMessage返回0,從而退出循環(huán)體。應(yīng)用程序可以使用PostQuitMessage來(lái)結(jié)束自己的消息循環(huán)。通常在主窗口的WM_DESTROY消息中調(diào)用。
 下面我們舉一個(gè)常見(jiàn)的小例子來(lái)說(shuō)明這個(gè)消息泵的運(yùn)用:
if (::PeekMessage(&msg, m_hWnd, WM_KEYFIRST,WM_KEYLAST, PM_REMOVE))
{
          if (msg.message == WM_KEYDOWN && msg.wParam == VK_ESCAPE)...
}
  這里我們接受所有的鍵盤(pán)消息,所以就用WM_KEYFIRST 和 WM_KEYLAST作為參數(shù)。最后一個(gè)參數(shù)可以是PM_NOREMOVE 或者 PM_REMOVE,表示消息信息是否應(yīng)該從消息隊(duì)列中刪除。                
   所以這段小代碼就是判斷是否按下了Esc鍵,如果是就進(jìn)行處理。

窗口過(guò)程
 窗口過(guò)程是一個(gè)用于處理所有發(fā)送到這個(gè)窗口的消息的函數(shù)。任何一個(gè)窗口類(lèi)都有一個(gè)窗口過(guò)程。同一個(gè)類(lèi)的窗口使用同樣的窗口過(guò)程來(lái)響應(yīng)消息。 系統(tǒng)發(fā)送消息給窗口過(guò)程將消息數(shù)據(jù)作為參數(shù)傳遞給他,消息到來(lái)之后,按照消息類(lèi)型排序進(jìn)行處理,其中的參數(shù)則用來(lái)區(qū)分不同的消息,窗口過(guò)程使用參數(shù)產(chǎn)生合適行為。
 一個(gè)窗口過(guò)程不經(jīng)常忽略消息,如果他不處理,它會(huì)將消息傳回到執(zhí)行默認(rèn)的處理。窗口過(guò)程通過(guò)調(diào)用DefWindowProc來(lái)做這個(gè)處理。窗口過(guò)程必須return一個(gè)值作為它的消息處理結(jié)果。大多數(shù)窗口只處理小部分消息和將其他的通過(guò)DefWindowProc傳遞給系統(tǒng)做默認(rèn)的處理。窗口過(guò)程被所有屬于同一個(gè)類(lèi)的窗口共享,能為不同的窗口處理消息。下面我們來(lái)看一下具體的實(shí)例:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 int wmId, wmEvent;
 PAINTSTRUCT ps;
 HDC hdc;
 TCHAR szHello[MAX_LOADSTRING];
 LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

 switch (message)
 {
  case WM_COMMAND:
         wmId    = LOWORD(wParam);
         wmEvent = HIWORD(wParam);
         // Parse the menu selections:
         switch (wmId)
         {
          case IDM_ABOUT:
             DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
             break;
          case IDM_EXIT:
             DestroyWindow(hWnd);
             break;
          default:
             return DefWindowProc(hWnd, message, wParam, lParam);
         }
   break;

  case WM_PAINT:
         hdc = BeginPaint(hWnd, &ps);
         // TODO: Add any drawing code here...
         RECT rt;
         GetClientRect(hWnd, &rt);
         DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
         EndPaint(hWnd, &ps);
         break;

  case WM_DESTROY:
         PostQuitMessage(0);
         break;
  default:
         return DefWindowProc(hWnd, message, wParam, lParam);
  }
  return 0;
}

消息分流器
  通常的窗口過(guò)程是通過(guò)一個(gè)switch語(yǔ)句來(lái)實(shí)現(xiàn)的,這個(gè)事情很煩,有沒(méi)有更簡(jiǎn)便的方法呢?有,那就是消息分流器,利用消息分流器,我們可以把switch語(yǔ)句分成更小的函數(shù),每一個(gè)消息都對(duì)應(yīng)一個(gè)小函數(shù),這樣做的好處就是對(duì)消息更容易管理。
  之所以被稱(chēng)為消息分流器,就是因?yàn)樗梢詫?duì)任何消息進(jìn)行分流。下面我們做一個(gè)函數(shù)就很清楚了:
void MsgCracker(HWND hWnd,int id,HWND hWndCtl,UINT codeNotify)
{
      switch(id)
      {
     case ID_A:
                  if(codeNotify==EN_CHANGE)...
                  break;
     case ID_B:
                  if(codeNotify==BN_CLICKED)...
                  break;
             ....
       }
}
然后我們修改一下窗口過(guò)程:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
       switch(message)
      {
             HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);
             HANDLE_MSG(hWnd,WM_DESTROY,MsgCracker);
           default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
   }
  return 0;
}
在WindowsX.h中定義了如下的HANDLE_MSG宏:
   #define HANDLE_MSG(hwnd,msg,fn) \
             switch(msg): return HANDLE_##msg((hwnd),(wParam),(lParam),(fn));
實(shí)際上,HANDLE_WM_XXXX都是宏,例如:HANDLE_MSG(hWnd,WM_COMMAND,MsgCracker);將被轉(zhuǎn)換成如下定義:
   #define HANDLE_WM_COMMAND(hwnd,wParam,lParam,fn)\
             ((fn)((hwnd),(int)(LOWORD(wParam)),(HWND)(lParam),(UINT)HIWORD(wParam)),0L);
好了,事情到了這一步,應(yīng)該一切都明朗了。
不過(guò),我們發(fā)現(xiàn)在windowsx.h里面還有一個(gè)宏:FORWARD_WM_XXXX,我們還是那WM_COMMAND為例,進(jìn)行分析:
   #define FORWARD_WM_COMMAND(hwnd, id, hwndCtl, codeNotify, fn) \
     (void)(fn)((hwnd), WM_COMMAND, MAKEWPARAM((UINT)(id),(UINT)(codeNotify)), (LPARAM)(HWND)(hwndCtl))
所以實(shí)際上,F(xiàn)ORWARD_WM_XXXX將消息參數(shù)進(jìn)行了重新構(gòu)造,生成了wParam && lParam,然后調(diào)用了我們定義的函數(shù)。
好了,事情到這里也算是也段落了,下次我們?cè)诜治鱿⒃贛FC中的處理。

posted @ 2009-02-21 08:37 wrh 閱讀(451) | 評(píng)論 (0)編輯 收藏
僅列出標(biāo)題
共25頁(yè): First 13 14 15 16 17 18 19 20 21 Last 

導(dǎo)航

<2008年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

統(tǒng)計(jì)

常用鏈接

留言簿(19)

隨筆檔案

文章檔案

收藏夾

搜索

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99在线|亚洲一区二区| 亚洲欧美成人综合| 亚洲一区999| 亚洲精品一区二| 伊人春色精品| 亚洲区一区二| 99精品视频免费观看视频| 亚洲乱码国产乱码精品精| 亚洲精品韩国| 亚洲色图综合久久| 欧美在线观看视频在线| 久久久99免费视频| 欧美高清在线观看| 日韩视频永久免费观看| 亚洲一区免费视频| 欧美一区二区在线看| 久久亚洲美女| 欧美色综合天天久久综合精品| 国产精品video| 国产在线不卡| 亚洲精品自在久久| 欧美亚洲综合久久| 欧美激情国产高清| 一本色道久久综合精品竹菊| 欧美一区午夜精品| 欧美精品久久久久久久久老牛影院 | 国产亚洲观看| 亚洲电影免费在线| 亚洲婷婷综合色高清在线| 久久久精品国产免费观看同学| 老司机成人在线视频| 亚洲欧洲精品一区二区精品久久久| 亚洲娇小video精品| 午夜国产精品影院在线观看| 欧美二区在线| 国产一区自拍视频| 亚洲一区二区三区免费视频| 蜜桃久久av一区| 亚洲一区二区三区在线看| 欧美1区2区视频| 中文在线不卡| 国产女人水真多18毛片18精品视频| 在线观看亚洲一区| 午夜视频在线观看一区二区三区| 免费欧美在线视频| 亚洲欧美国产高清va在线播| 欧美成人午夜激情| 精品va天堂亚洲国产| 欧美一区二粉嫩精品国产一线天| 91久久精品美女高潮| 久久gogo国模啪啪人体图| 欧美日韩三区四区| 日韩亚洲欧美一区二区三区| 免费成人黄色| 久久本道综合色狠狠五月| 国产精品久久久久aaaa| 亚洲调教视频在线观看| 亚洲欧洲在线观看| 欧美成人免费网站| 亚洲激情在线观看| 欧美激情一二区| 美女在线一区二区| 亚洲国产专区校园欧美| 美女日韩欧美| 免费观看在线综合色| 亚洲大片精品永久免费| 麻豆精品一区二区综合av| 久久精品人人做人人综合| 国内精品久久久久久久果冻传媒 | 久久久久成人网| 欧美一区二区三区视频免费播放| 国产精品入口夜色视频大尺度| 亚洲一区二区三区在线视频| 日韩一区二区免费看| 欧美三区免费完整视频在线观看| 亚洲午夜极品| 亚洲免费视频在线观看| 国产一区二区精品久久91| 久久免费视频在线观看| 久久精品一区二区三区中文字幕| 狠狠干综合网| 亚洲国内精品| 国产精品v欧美精品v日韩精品 | 国产视频一区欧美| 久久免费视频在线| 欧美成人自拍视频| 亚洲综合视频网| 欧美一区二区久久久| 在线观看亚洲一区| 亚洲九九精品| 国产午夜精品久久久久久免费视 | 亚洲高清网站| 日韩一级精品视频在线观看| 亚洲三级色网| 午夜视频久久久| 久久精品国产综合| 亚洲精品视频在线观看免费| 日韩网站在线观看| 中文国产成人精品| 黑人极品videos精品欧美裸| 亚洲国产第一页| 国产精品久久二区二区| 久久久亚洲一区| 欧美日韩成人| 久久一区二区视频| 欧美日韩美女一区二区| 久久久7777| 欧美私人网站| 亚洲大片在线| 国产视频自拍一区| 日韩视频在线观看免费| 伊人成人在线视频| 亚洲欧美清纯在线制服| 亚洲美女中出| 久久午夜精品一区二区| 亚洲欧美色一区| 欧美第十八页| 美女图片一区二区| 国产精品一卡二| 亚洲美女一区| 亚洲精品日韩在线| 久久久久高清| 久久精品国产91精品亚洲| 欧美午夜精品久久久久久人妖| 亚洲大胆人体视频| 怡红院精品视频| 久久成人一区| 欧美在线关看| 国产伦精品一区| 亚洲一区二区三区高清| 亚洲视频视频在线| 欧美日韩国产成人在线观看| 欧美激情1区2区| 亚洲国产精品成人va在线观看| 欧美一区二区三区久久精品| 亚洲女人天堂av| 欧美日韩亚洲一区二| 亚洲欧洲精品一区二区三区| 亚洲欧洲精品一区二区三区波多野1战4| 欧美一区二区三区视频免费播放| 欧美在线观看你懂的| 国产午夜精品全部视频在线播放| 亚洲午夜三级在线| 亚洲欧美精品| 国产精品夜色7777狼人 | 欧美高清一区二区| 亚洲精品国产精品久久清纯直播| 蜜桃av综合| 亚洲人成7777| 亚洲桃色在线一区| 国产精品av免费在线观看| 亚洲午夜91| 久久九九免费| 亚洲国产精品第一区二区三区| 久久夜精品va视频免费观看| 亚洲第一精品电影| 亚洲精选国产| 国产精品视频一区二区三区| 亚洲天堂免费观看| 欧美一区午夜精品| 国产亚洲欧美日韩精品| 久久亚洲免费| 亚洲日本va在线观看| 午夜精品福利视频| 国模 一区 二区 三区| 蜜臀av在线播放一区二区三区| 亚洲国产精品久久久| 亚洲无亚洲人成网站77777| 国产欧美日韩视频一区二区| 久久久久久9| 日韩视频一区二区在线观看 | 久久五月天婷婷| 夜色激情一区二区| 美女免费视频一区| 亚洲在线免费| 亚洲国产成人久久综合| 欧美另类videos死尸| 欧美一级成年大片在线观看| 欧美激情视频一区二区三区免费| 亚洲一区二区精品在线| 在线观看亚洲专区| 国产精品午夜电影| 欧美激情视频网站| 香蕉久久一区二区不卡无毒影院 | 亚洲电影网站| 国产女人水真多18毛片18精品视频| 美女主播一区| 欧美一区二区日韩一区二区| 亚洲日本欧美在线| 鲁大师影院一区二区三区| 亚洲综合电影一区二区三区| 91久久精品日日躁夜夜躁欧美 | 欧美一区在线看| 一区二区三区精品国产| 亚洲福利精品| 狼狼综合久久久久综合网| 午夜精品视频一区| 亚洲视频一区在线| 亚洲精品一区二区三区av| 在线观看中文字幕亚洲|