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

 
函數(shù)名:

 

  SetWindowPos

頭文件:

  winuser.h

函數(shù)原型:

  BOOL SetWindowPos
  (
  HWND hWnd, //窗口句柄
  HWND hWndInsertAfter, //排列順序的句柄
  int X, //水平坐標(biāo)
  int Y, //垂直坐標(biāo)
  int cx, //寬
  int cy, //高
  UINT uFlags //窗口定位標(biāo)識(shí)
  );

說(shuō)明:

  這個(gè)函數(shù)能改變窗口的大小、位置和設(shè)置子窗口、彈出窗口或頂層窗口的排列順序。
  返回值:

  BOOL,如果返回值非零表示成功,返回零表示失敗。錯(cuò)誤信息請(qǐng)參看GetLastError函數(shù)。

參數(shù)表:

  參數(shù) 類型及說(shuō)明
  hwnd HWND,欲定位的窗口句柄
  hWndInsertAfter HWND,置于hwnd前面的窗口句柄。這個(gè)參數(shù)必須是窗口的句柄或是下面的值之一:    HWND_BOTTOM 將窗口置于其它所有窗口的底部
  HWND_NOTOPMOST 將窗口置于其它所有窗口的頂部,并位于任何最頂部窗口的后面。如果這個(gè)窗口非頂部窗口,這個(gè)標(biāo)記對(duì)該窗口并不產(chǎn)生影響
  HWND_TOP 將窗口置于它所有窗口的頂部
  HWND_TOPMOST 將窗口置于其它所有窗口的頂部,并位于任何最頂部窗口的前面。即使這個(gè)窗口不是活動(dòng)窗口,也維持最頂部狀態(tài)

x: 
 
  int,指定窗口新的X坐標(biāo)

Y:  

  int,指定窗口新的Y坐標(biāo)

cx:  

  int,指定窗口新的寬度

cy:  

  int,指定窗口新的高度

wFlags:

  UINT,指定窗口狀態(tài)和位置的標(biāo)記。這個(gè)參數(shù)使用下面值的組合: SWP_DRAWFRAME 圍繞窗口畫(huà)一個(gè)框
  SWP_FRAMECHANGED 發(fā)送一條WM_NCCALCSIZE消息進(jìn)入窗口,即使窗口的大小沒(méi)有發(fā)生改變。如果不指定這個(gè)參數(shù),消息WM_NCCALCSIZE只有在窗口大小發(fā)生改變時(shí)才發(fā)送
  SWP_HIDEWINDOW 隱藏窗口
  SWP_NOACTIVATE 不激活窗口
  SWP_NOCOPYBITS 屏蔽客戶區(qū)域
  SWP_NOMOVE 保持當(dāng)前位置(X和Y參數(shù)將被忽略)
  SWP_NOOWNERZORDER 不改變所有窗口的位置和排列順序
  SWP_NOREDRAW 窗口不自動(dòng)重畫(huà)
  SWP_NOREPOSITION 與SWP_NOOWNERZORDER標(biāo)記相同
  SWP_NOSENDCHANGING 防止這個(gè)窗口接受WM_WINDOWPOSCHANGING消息
  SWP_NOSIZE 保持當(dāng)前大小(cx和cy會(huì)被忽略)
  SWP_NOZORDER 保持窗口在列表的當(dāng)前位置(hWndInsertAfter將被忽略)
  SWP_SHOWWINDOW 顯示窗口


備注:

  如果設(shè)置了SWP_SHOWWINDOW或SWP_HIDEWINDOW標(biāo)記,這個(gè)窗口不發(fā)生移動(dòng)或改變大小。窗口成為最頂級(jí)窗口后,它的所有子窗口也會(huì)進(jìn)入最頂級(jí)。一旦將其設(shè)為非最頂級(jí),則它的所有子窗口也會(huì)轉(zhuǎn)為非最頂級(jí)。

相關(guān)函數(shù):

  MoveWindow,SetActiveWindow,SetForegroundWindow

例子:

  //設(shè)置頂層窗口
  SetWindowPos( Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE||SWP_NOSIZE);

  //取消頂層窗口
  SetWindowPos( Handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE||SWP_NOSIZE);

函數(shù)功能:該函數(shù)改變一個(gè)子窗口,彈出式窗口式頂層窗口的尺寸,位置和Z序。子窗口,彈出式窗口,及頂層窗口根據(jù)它們?cè)谄聊簧铣霈F(xiàn)的順序排序、頂層窗口設(shè)置的級(jí)別最高,并且被設(shè)置為Z序的第一個(gè)窗口。

     函數(shù)原型:BOOL SetWindowPos(HWN hWnd,HWND hWndlnsertAfter,int X,int Y,int cx,int cy,UNIT.Flags);

     參數(shù):

     hWnd:窗口句柄。

     hWndlnsertAfter:在z序中的位于被置位的窗口前的窗口句柄。該參數(shù)必須為一個(gè)窗口句柄,或下列值之一:

     HWND_BOTTOM:將窗口置于Z序的底部。如果參數(shù)hWnd標(biāo)識(shí)了一個(gè)頂層窗口,則窗口失去頂級(jí)位置,并且被置在其他窗口的底部。

     HWND_DOTTOPMOST:將窗口置于所有非頂層窗口之上(即在所有頂層窗口之后)。如果窗口已經(jīng)是非頂層窗口則該標(biāo)志不起作用。

     HWND_TOP:將窗口置于Z序的頂部。

     HWND_TOPMOST:將窗口置于所有非頂層窗口之上。即使窗口未被激活窗口也將保持頂級(jí)位置。

     查g看該參數(shù)的使用方法,請(qǐng)看說(shuō)明部分。

     x:以客戶坐標(biāo)指定窗口新位置的左邊界。

     Y:以客戶坐標(biāo)指定窗口新位置的頂邊界。

     cx:以像素指定窗口的新的寬度。

     cy:以像素指定窗口的新的高度。

     uFlags:窗口尺寸和定位的標(biāo)志。該參數(shù)可以是下列值的組合:

     SWP_ASNCWINDOWPOS:如果調(diào)用進(jìn)程不擁有窗口,系統(tǒng)會(huì)向擁有窗口的線程發(fā)出需求。這就防止調(diào)用線程在其他線程處理需求的時(shí)候發(fā)生死鎖。

     SWP_DEFERERASE:防止產(chǎn)生WM_SYNCPAINT消息。

     SWP_DRAWFRAME:在窗口周圍畫(huà)一個(gè)邊框(定義在窗口類描述中)。

     SWP_FRAMECHANGED:給窗口發(fā)送WM_NCCALCSIZE消息,即使窗口尺寸沒(méi)有改變也會(huì)發(fā)送該消息。如果未指定這個(gè)標(biāo)志,只有在改變了窗口尺寸時(shí)才發(fā)送WM_NCCALCSIZE。

     SWP_HIDEWINDOW;隱藏窗口。

     SWP_NOACTIVATE:不激活窗口。如果未設(shè)置標(biāo)志,則窗口被激活,并被設(shè)置到其他最高級(jí)窗口或非最高級(jí)組的頂部(根據(jù)參數(shù)hWndlnsertAfter設(shè)置)。

     SWP_NOCOPYBITS:清除客戶區(qū)的所有內(nèi)容。如果未設(shè)置該標(biāo)志,客戶區(qū)的有效內(nèi)容被保存并且在窗口尺寸更新和重定位后拷貝回客戶區(qū)。

     SWP_NOMOVE:維持當(dāng)前位置(忽略X和Y參數(shù))。

     SWP_NOOWNERZORDER:不改變z序中的所有者窗口的位置。

     SWP_NOREDRAW:不重畫(huà)改變的內(nèi)容。如果設(shè)置了這個(gè)標(biāo)志,則不發(fā)生任何重畫(huà)動(dòng)作。適用于客戶區(qū)和非客戶區(qū)(包括標(biāo)題欄和滾動(dòng)條)和任何由于窗回移動(dòng)而露出的父窗口的所有部分。如果設(shè)置了這個(gè)標(biāo)志,應(yīng)用程序必須明確地使窗口無(wú)效并區(qū)重畫(huà)窗口的任何部分和父窗口需要重畫(huà)的部分。

     SWP_NOREPOSITION;與SWP_NOOWNERZORDER標(biāo)志相同。

     SWP_NOSENDCHANGING:防止窗口接收WM_WINDOWPOSCHANGING消息。

     SWP_NOSIZE:維持當(dāng)前尺寸(忽略cx和Cy參數(shù))。

     SWP_NOZORDER:維持當(dāng)前Z序(忽略hWndlnsertAfter參數(shù))。

     SWP_SHOWWINDOW:顯示窗口。

     返回值:如果函數(shù)成功,返回值為非零;如果函數(shù)失敗,返回值為零。若想獲得更多錯(cuò)誤消息,請(qǐng)調(diào)用GetLastError函數(shù)。

     備注:如果設(shè)置了SWP_SHOWWINDOW和SWP_HIDEWINDOW標(biāo)志,則窗口不能被移動(dòng)和改變大小。如果使用SetWindowLoog改變了窗口的某些數(shù)據(jù),則必須調(diào)用函數(shù)SetWindowPos來(lái)作真正的改變。使用下列的組合標(biāo)志:SWP_NOMOVEISWP_NOSIZEISWP_FRAMECHANGED。

     有兩種方法將窗口設(shè)為最頂層窗口:一種是將參數(shù)hWndlnsertAfter設(shè)置為HWND_TOPMOST并確保沒(méi)有設(shè)置SWP_NOZORDER標(biāo)志;另一種是設(shè)置窗口在Z序中的位置以使其在其他存在的窗口之上。當(dāng)一個(gè)窗口被置為最頂層窗口時(shí),屬于它的所有窗口均為最頂層窗口,而它的所有者的z序并不改變。

     如果HWND_TOPMOST和HWND_NOTOPMOST標(biāo)志均未指定,即應(yīng)用程序要求窗口在激活的同時(shí)改變其在Z序中的位置時(shí),在參數(shù)hWndinsertAfter中指定的值只有在下列條件中才使用:

     在hWndlnsertAfter參數(shù)中沒(méi)有設(shè)定HWND_NOTOPMOST和HWND_TOPMOST標(biāo)志。

     由hWnd參數(shù)標(biāo)識(shí)的窗口不是激活窗口。

     如果未將一個(gè)非激活窗口設(shè)定到z序的頂端,應(yīng)用程序不能激活該窗口。應(yīng)用程序可以無(wú)任何限制地改變被激活窗口在Z序中的位置,或激活一個(gè)窗口并將其移到最高級(jí)窗口的頂部或非最高級(jí)窗口的頂部。

     如果一個(gè)頂層窗口被重定位到z序的底部(HWND_BOTTOM)或在任何非最高序的窗口之后,該窗口就不再是最頂層窗口。當(dāng)一個(gè)最頂層窗口被置為非最頂級(jí),則它的所有者窗口和所屬者窗口均為非最頂層窗口。

     一個(gè)非最頂端窗口可以擁有一個(gè)最頂端窗口,但反之則不可以。任何屬于頂層窗口的窗口(例如一個(gè)對(duì)話框)本身就被置為頂層窗口,以確保所有被屬窗口都在它們的所有者之上。

     如果應(yīng)用程序不在前臺(tái),但應(yīng)該位于前臺(tái),就應(yīng)調(diào)用SetForegroundWindow函數(shù)來(lái)設(shè)置。

     Windows CE:如果這是一個(gè)可見(jiàn)的頂層窗口,并且未指定SWP_NOACTIVATE標(biāo)志,則這個(gè)函數(shù)將激活窗口、如果這是當(dāng)前的激活窗口,并且指定了SWP_NOACTIVATE或SWP_HIDEWINDOW標(biāo)志,則激活另外一個(gè)可見(jiàn)的頂層窗口。

     當(dāng)在這個(gè)函數(shù)中的nFlags參數(shù)里指定了SWP_FRAMECHANGED標(biāo)志時(shí),WindowsCE重畫(huà)窗口的整個(gè)非客戶區(qū),這可能會(huì)改變客戶區(qū)的大小。這也是重新計(jì)算客戶區(qū)的唯一途徑,也是通過(guò)調(diào)用SetwindowLong函數(shù)改變窗口風(fēng)格后通常使用的方法。

     SetWindowPos將使WM_WINDOWPOSCHANGED消息向窗口發(fā)送,在這個(gè)消息中傳遞的標(biāo)志與傳遞給函數(shù)的相同。這個(gè)函數(shù)不傳遞其他消息。

     Windows CE 1.0不支持在hWndlnsertAber參數(shù)中的HWND_TOPMOST和HWND_NOTOPMOST常量。

posted @ 2009-06-06 18:49 wrh 閱讀(7195) | 評(píng)論 (0)編輯 收藏

目 錄

一. 視頻捕獲快速入門(mén)

二.基本的捕獲設(shè)置

          1.設(shè)置捕獲速度:

          2.設(shè)置終止捕獲

          3.捕獲的時(shí)間限制

三.關(guān)于捕獲窗口

          1.創(chuàng)建一個(gè)AVICAP捕獲窗口

          2.將一個(gè)捕獲窗口連接至捕獲設(shè)備

          3. 父窗口與子窗口的交互

          4.捕獲窗口的狀態(tài)

四.視頻捕獲驅(qū)動(dòng)和音頻驅(qū)動(dòng)

          1.視頻捕獲驅(qū)動(dòng)的性能:

          2.視頻對(duì)話框:

          3.PREVIEW 和 OVERLAY模式:

          4.視頻格式

          5.視頻捕獲設(shè)置

          6.聲頻格式

五.使用視頻捕獲

        1.創(chuàng)建捕獲窗口(CREATING A CAPTURE WINDOW)

        2.連接到捕獲驅(qū)動(dòng)(CONNECTING TO A CAPTURE DRIVER)

        3.列舉所有已安裝的捕獲驅(qū)動(dòng)(ENUMERATING INSTALLED CAPTURE DRIVERS)

        4.得到捕獲驅(qū)動(dòng)的性能(OBTAINING THE CAPABILITIES OF A CAPTURE DRIVER)

        5.得到捕獲窗口的狀態(tài)(OBTAINING THE STATUS OF A CAPTURE WINDOW)

        6.顯示對(duì)話框設(shè)置視頻特征(DISPLAYING DIALOG BOXES TO SET VIDEO CHARACTERISTICS)

        7.得到和設(shè)置視頻格式(OBTAINING AND SETTING THE VIDEO FORMAT)

        8. 預(yù)覽視頻(PREVIEWING VIDEO)

        9.將視頻設(shè)置為OVERLAY模式(ENABLING VIDEO OVERLAY)

        10.命名捕獲文件(NAMING THE CAPTURE FILE)

        11.格式化聲頻捕獲(FORMATTING AUDIO CAPTURE)

        12.改變視頻捕獲設(shè)置(CHANGING A VIDEO CAPTURE SETTING)

        13.捕獲數(shù)據(jù)(CAPTURING DATA)

        14.增加一個(gè)信息塊(ADDING AN INFORMATION CHUNK)

        15.在程序中加入一個(gè)回調(diào)函數(shù)(ADDING CALLBACK FUNCTIONS TO AN APPLICATION)

        16.創(chuàng)建一個(gè)狀態(tài)回調(diào)函數(shù)(CREATING A STATUS CALLBACK FUNCTION)

        17.創(chuàng)建一個(gè)錯(cuò)誤回調(diào)函數(shù)( CREATING AN ERROR CALLBACK FUNCTION)

        18.創(chuàng)建一個(gè)框架回調(diào)函數(shù)(CREATING A FRAME CALLBACK FUNCTION)

六.將四個(gè)標(biāo)準(zhǔn)對(duì)話框改成函數(shù)調(diào)用形式

         AUDIOFORMAT對(duì)話框

         VIDEOFORMAT對(duì)話框

         VIDEOSOURCE對(duì)話框

         VIDEO COMPRESSION對(duì)話框  

前 言

         視頻捕獲是指由專用的視頻采集卡捕獲聲頻和視頻信息,然后將其進(jìn)行數(shù)據(jù)化處理,再經(jīng)過(guò)軟件的壓縮進(jìn)行處理,這時(shí)就可對(duì)這些數(shù)據(jù)進(jìn)行保存、回放、傳輸?shù)雀鞣N操作。

         Windows專門(mén)提供了Video for Windows來(lái)對(duì)視頻處理進(jìn)行支持,提供的接口可以被大多數(shù)的視頻采集卡支持,并有多種視頻壓縮驅(qū)動(dòng)供選擇(當(dāng)然視頻壓縮可以自己開(kāi)發(fā)),采集卡支持?jǐn)z像頭,TV等多種輸入。


一. 視頻捕獲快速入門(mén)

          視頻捕捉將一個(gè)視頻流和音頻流數(shù)字化, 然后存儲(chǔ)在硬盤(pán)或其他存儲(chǔ)介質(zhì)上.

          一個(gè)AVICap視窗口句柄描述了聲頻與視頻流的細(xì)節(jié), 這樣就使你的應(yīng)用程序從AVI文件格式, 聲頻視頻緩沖管理, 低層聲頻視頻驅(qū)動(dòng)訪問(wèn)等等解脫出來(lái), AVICap為應(yīng)用程序提供了一個(gè)靈活的介面, 你可以僅僅使用如下幾行代碼就可以將視頻捕捉加入你的程序:

hWndC = capCreateCaptureWindow ( "My Own Capture Window",

WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, nID);

SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0 /* wIndex */, 0L);

SendMessage (hWndC, WM_CAP_SEQUENCE, 0, 0L);

           一個(gè)宏其實(shí)也是使用SendMessage, 只不過(guò)提供給程序一個(gè)更易讀的代碼而已, 下面的這些示例就是使用宏的方法將視頻捕捉加入程序:

hWndC = capCreateCaptureWindow ( "My Own Capture Window",

WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, hwndParent, nID);

capDriverConnect (hWndC, 0);

capCaptureSequence (hWndC);


          當(dāng)你創(chuàng)建了一個(gè)AVICap類的捕捉窗口并將它連接到一個(gè)視頻驅(qū)動(dòng)時(shí), 此捕捉窗口即可以開(kāi)始捕捉數(shù)據(jù), 你的程序可以簡(jiǎn)單的發(fā)送WM_CAP_SEQUENCE消息(或者使用capCaptureSequence宏)來(lái)開(kāi)始捕捉.

          如果是缺省的設(shè)置, WM_CAP_SEQUENCE會(huì)開(kāi)始捕捉視頻音頻流到CAPTURE.AVI文件中, 直到下面的某一事件發(fā)生為止:

用戶按下了ESC鍵或者一個(gè)鼠標(biāo)鍵

你的應(yīng)用程序終止或異常中斷捕捉操作

磁盤(pán)已滿


              在一個(gè)應(yīng)用程序里, 你可以發(fā)送WM_CAP_STOP消息來(lái)終止捕捉數(shù)據(jù)(或者使用capCaptureStop宏), 你也可以發(fā)送WM_CAP_ABORT消息(或者使用capCaptureAbort宏)來(lái)終止.


二.基本的捕獲設(shè)置

          基本的捕獲設(shè)置包括:設(shè)置捕獲速度(每秒捕獲多少幀),是否同時(shí)捕獲聲頻,捕獲緩沖,允許最大丟失多少幀,是否使用DOS內(nèi)存,以及用鍵盤(pán)的哪個(gè)鍵或鼠標(biāo)的哪個(gè)鍵來(lái)終止捕獲等等。這些基本的設(shè)置都可以使用CAPTUREPARAMS結(jié)構(gòu)來(lái)描述,你可以使用capCaptureGetSetup宏來(lái)得到當(dāng)前的設(shè)置,然后改變此結(jié)構(gòu)的成員變量,再使用capCaptureSetSetup宏設(shè)置新的設(shè)置。

例如:

1.設(shè)置捕獲速度:

           捕捉速度是指捕捉任務(wù)每秒鐘捕獲的幀數(shù), 你可以發(fā)送WM_CAP_GET_SEQUENCE_SETUP消息(或者使用capCaptureGetSetup宏)來(lái)得到當(dāng)前的捕捉速度, 當(dāng)前的捕捉速度保存在CAPTUREPARAMS結(jié)構(gòu)的dwRequestMicroSecPerFrame成員變量中, 你可以通過(guò)設(shè)置此變量來(lái)改變當(dāng)前設(shè)置, 單位是每毫秒連續(xù)的幀數(shù), 你可以發(fā)送WM_CAP_SET_SEQUENCE_SETUP消息(或者使用capCaptureSetSetup宏), dwRequestMicroSecPerFrame的值是66667, 相當(dāng)于每秒15幀.


2.設(shè)置終止捕獲

           你可以允許用戶按下某鍵或某組合鍵或者鼠標(biāo)的左右鍵來(lái)終止一個(gè)捕獲任務(wù), 如果是實(shí)時(shí)的捕獲, 則捕獲的文件將會(huì)被丟棄; 如果是單步捕獲, 在終止之前所捕獲的內(nèi)容將會(huì)被保存.

          你可以通過(guò)發(fā)送WM_CAP_GETQUENCE_SETUP消息(或者使用capCaptureGetSetup宏)來(lái)得到當(dāng)前的設(shè)置, 當(dāng)前的按鍵設(shè)置保存在CAPTUREPARAMS的vKeyAbort成員中, 當(dāng)前的鼠標(biāo)設(shè)置保存在fAbortLeftMouse和fAbortRightMouse成員中. 你可以設(shè)置新的按鍵或按鍵組合, 或者鼠標(biāo)左右鍵, 當(dāng)你修改的CAPTUREPARAMS后,應(yīng)該發(fā)送WM_CAP_SET_SEQUENCE_SETUP消息來(lái)進(jìn)行更新(或者使用capCaptureSetSetup宏). 缺省的按鍵是VK_ESCAPE. 你必須在指定按鍵之前使用RegisterHotKey函數(shù), 鼠標(biāo)缺省的值是fAbortLeftMouse和fAbortRightMouse都為T(mén)RUE.


3.捕獲的時(shí)間限制

           CAPTUREPARAMS結(jié)構(gòu)中的fLimitEnabled指示是否有時(shí)間限度, wTimeLimit指示最大的持續(xù)時(shí)間, 單位為秒.

          得到fLimitEnabled和wTimeLimit的值可以發(fā)送WM_CAP_GET_SEQUENCE_SETUP消息(或使用capCatureGetSetup宏), 當(dāng)設(shè)置了這些成員變量后, 應(yīng)該發(fā)送消息WM_CAP_SET_SEQUENCE_SETUP消息(或capCaptureSetSetup宏)來(lái)更新CAPTUREPARAMS結(jié)構(gòu).


三.關(guān)于捕獲窗口

        在捕獲之前必須創(chuàng)建一個(gè)捕獲窗口(capture window),在發(fā)送消息或使用宏的過(guò)程中都需要使用此窗口。

1.創(chuàng)建一個(gè)AVICap捕獲窗口

        你可以使用capCreateCaptureWindow函數(shù)來(lái)創(chuàng)建一個(gè)AVICap捕獲窗口, 此函數(shù)將會(huì)返回一個(gè)句柄, 此句柄以后在發(fā)送消息時(shí)要用.

        你可以在一個(gè)程序里創(chuàng)建一個(gè)或多個(gè)捕獲窗口, 然后給每一個(gè)窗口連接不同的捕獲設(shè)置.


2.將一個(gè)捕獲窗口連接至捕獲設(shè)備

           你可以動(dòng)態(tài)的在一個(gè)捕獲窗口與一個(gè)捕獲設(shè)備之前連接或斷接, 你可以發(fā)送WM_CAP_DRIVER_CONNECT消息來(lái)使一個(gè)捕獲窗口與一個(gè)捕獲設(shè)備連接或關(guān)聯(lián). 當(dāng)連接上以后, 你就可以通過(guò)捕獲窗口向捕獲設(shè)備發(fā)送各種消息.

        如果你的系統(tǒng)里裝有多個(gè)捕獲設(shè)備, 你可以在發(fā)送WM_CAP_DRIVER_CONNECT消息時(shí)用wParam參數(shù)指定使用哪一個(gè), 此參數(shù)是登記在SYSTEM.INI文件的[drivers]一節(jié)里的列表中的某一項(xiàng), 0為第一個(gè).

          你可以使用capGetDriverDescription函數(shù)來(lái)得到已安裝的捕獲設(shè)備的名稱及版本, 這樣你的程序就可以列舉所有已安裝的捕獲設(shè)備和驅(qū)動(dòng), 這樣用戶就可以選擇其中的一個(gè)來(lái)與你的捕獲窗口連接.

         你可以發(fā)送WM_CAP_DRIVER_GET_NAME消息(或capDriverGetName宏)來(lái)得到連接到捕獲窗口的捕獲設(shè)備的名稱, 得到版本發(fā)送WM_CAP_DRIVER_GET_VERSION消息(或capDriverGetVersion宏)

         你可以發(fā)送WM_CAP_DRIVER_DISCONNECT消息(或capDriverDisconnect宏)來(lái)斷接.


3. 父窗口與子窗口的交互

           一些象WM_PALETTECHANGED和WM_QUERYNEWPALETTE的系統(tǒng)級(jí)消息只能發(fā)送到頂級(jí)窗口或OVERLAPPED窗口, 如果一個(gè)捕獲窗口是子窗口,就必須通過(guò)父窗口轉(zhuǎn)送.

         同樣的, 如果父窗口的尺寸改變了, 它就需要通知捕獲窗口, 相反地, 如果捕獲窗口的尺寸改變了, 捕獲窗口就需要發(fā)送消息給父窗口, 一個(gè)簡(jiǎn)單的方法就是始終保持捕獲窗口的尺寸與視頻流的尺寸一致, 并隨時(shí)將尺寸的改變通知父窗口.


4.捕獲窗口的狀態(tài)

          你可以發(fā)送WM_CAP_GET_STATUS消息(或capGetStatus宏)來(lái)得到當(dāng)前捕獲窗口的狀態(tài), 得到的是一個(gè)CAPSTATUS結(jié)構(gòu)的拷貝, 它包含圖片的尺寸, 卷軸的當(dāng)前位置, overlay和preview是否已設(shè)置.

        因?yàn)镃APSTATUS信息是動(dòng)態(tài)的, 你的程序應(yīng)該只要捕獲的視頻流的尺寸或格式可能發(fā)生了改變就應(yīng)該進(jìn)行刷新(例如: 顯示了捕獲設(shè)備的視頻格式以后).

        改變捕獲窗口的尺寸并不影響實(shí)際的捕獲的視頻流的尺寸, 視頻捕獲設(shè)備的格式對(duì)話框捕獲頻流的尺寸.


四.視頻捕獲驅(qū)動(dòng)和音頻驅(qū)動(dòng)

1.視頻捕獲驅(qū)動(dòng)的性能:

          你可以通過(guò)發(fā)送WM_CAP_DRIVER_GET_CAPS消息(或者capDriverGetCaps宏)來(lái)得到當(dāng)前連接的視頻驅(qū)動(dòng)的硬件性能. 得到的信息保存在CAPDRIVERCAPS結(jié)構(gòu)中.


2.視頻對(duì)話框:

          每一個(gè)視頻驅(qū)動(dòng)能夠提供四個(gè)對(duì)話框來(lái)控制視頻捕獲和數(shù)字化處理, 定義壓縮品質(zhì)等, 這些對(duì)話框都定義在視頻捕獲驅(qū)動(dòng)中.

          Video Source對(duì)話框用于控制選擇視頻來(lái)源, 此對(duì)話框列舉了此視頻捕獲卡連接的所有視頻源(典型的例如:SVHS和合成輸入), 并提供了改變色調(diào), 對(duì)比度, 飽和度. 如果視頻驅(qū)動(dòng)支持此對(duì)話框, 你就可以顯示并更新它, 使用WM_CAP_DLG_VIDEOSOURCE消息(或capDlgVideoSource宏).

           Video Format對(duì)話框定義視頻幀的尺寸以及精度, 視頻捕獲卡的壓縮設(shè)置. 如果卡支持的話, 可以發(fā)送消息WM_CAP_DLG_VIDEOFORMAT消息或(capDlgVideoFormat宏).

           Video Display對(duì)話框控制在視頻捕獲期間在顯示器上的顯示, 此控制不會(huì)影響視頻數(shù)字?jǐn)?shù)據(jù), 但是他們可能會(huì)影響數(shù)字信號(hào)的表現(xiàn)形式, 例如: 如果捕獲設(shè)備支持overlay, 可能允許改變色調(diào)和飽和度, 關(guān)鍵色彩 或者overlay隊(duì)列. 如果卡支持, 你可以發(fā)送WM_CAP_DLG_VIDEODISPLAY消息(或者使用capDlgVideoDisplay宏).

           Video Compression對(duì)話框控制壓縮品質(zhì), 如果卡支持, 發(fā)送消息WM_CAP_DLG_VIDEOCOMPRESSION(或capDlgVideoCompression宏).


3.Preview 和 Overlay模式:

                 一個(gè)視頻捕獲驅(qū)動(dòng)對(duì)進(jìn)入的視頻流有兩種工作模式: Preview模式和overlay模式, 如果一個(gè)捕獲驅(qū)動(dòng)能夠執(zhí)行兩種方法, 用戶可以在其中選擇一種.

               Preview模式把從捕獲硬件傳來(lái)的數(shù)據(jù)送入系統(tǒng)內(nèi)存并使用圖形設(shè)備介面(GDI)將數(shù)字化幀顯示在捕獲窗口內(nèi). 應(yīng)用程序可以在父窗口失去焦點(diǎn)時(shí)減緩顯示速度, 當(dāng)重新又得到焦點(diǎn)后加快顯示速度, 此種模式要占用大量CPU時(shí)間.

有三種消息控制Preview操作:

WM_CAP_SET_PREIVEW消息(capPreview宏)允許或禁止preview模式

WM_CAP_SET_PREVIEWRATE(capPreviewRate宏)當(dāng)幀在preview模式顯示時(shí)設(shè)置速度.

WM_CAP_SET_SCALE(capPreviewScale宏)允許或禁止preview視頻的縮放比例.

          當(dāng)preview和scaling同時(shí)使用, 捕獲的視頻幀將會(huì)根據(jù)捕獲窗口的尺寸自動(dòng)縮放, 允許preview模式會(huì)自動(dòng)關(guān)閉overlay模式.

                      overlay模式是一個(gè)硬件函數(shù)它將數(shù)據(jù)送入捕獲緩沖區(qū)中因而不占用CPU資源. 你可以發(fā)送消息WM_CAP_SET_OVERLAY(或capOverlay宏)給捕獲窗口來(lái)啟用或終止overlay模式, 允許overlay模式會(huì)自動(dòng)禁止preview模式.

               你同時(shí)也可以在preview模式或overlay模式里發(fā)送WM_CAP_SET_SCROLL消息(或capSetScrollPos宏)來(lái)設(shè)置視頻幀的客戶區(qū)卷軸位置.


4.視頻格式

            你可以通過(guò)發(fā)送WM_CAP_GET_VIDEOFORMAT消息(或capGetVideoFormat和capGetVideoFormatSize宏)來(lái)得到視頻格式的結(jié)構(gòu)或結(jié)構(gòu)的尺寸. 你可以通過(guò)發(fā)送CAP_SET_VIDEOFORMAT消息(或capSetVideoFormat宏)來(lái)設(shè)置視頻格式.


5.視頻捕獲設(shè)置

           CAPTUREPARMS結(jié)構(gòu)包含了對(duì)視頻捕獲流的控制參數(shù), 你可以完成以下這些任務(wù):

指定幀數(shù)

指定分配多少視頻緩沖

允許或禁止聲頻捕獲

指定捕獲的時(shí)間間隔

指定在捕獲的過(guò)程中是否使用MCI設(shè)置(VCR或者videodisc)

指定終止流的鍵盤(pán)或鼠標(biāo)

specify the type of video averaging applied during capture.


得到:WM_CAP_GET_SEQUENCE_SETUP消息(或capCaptureGetSetup宏)

設(shè)置:WM_CAP_SET_SEQUENCE_SETUP消息(或capCaptureSetSetup宏)


6.聲頻格式

               你可以通過(guò)發(fā)送WM_CAP_GET_AUDIOFORMAT消息(或capGetAudioFormat宏和capGetAudioFormatSize宏)來(lái)得到當(dāng)前捕獲音頻數(shù)據(jù)的格式或尺寸格式。缺省的聲頻格式是:?jiǎn)温暤馈?位、11kHz PCM。 當(dāng)你使用WM_CAP_GET_AUDIOFORMAT時(shí),總是使用WAVEFORMATEX結(jié)構(gòu)。

             設(shè)置發(fā)送消息WM_CAP_SET_AUDIOFORMAT消息(或capSetAudioFormat宏),可以傳送WAVEFORMAT,WAVEFORMATEX,PCMWAVEFORMAT結(jié)構(gòu)指針。

五.使用視頻捕獲

1.創(chuàng)建捕獲窗口(Creating a Capture Window)

hWndC = capCreateCaptureWindow (

(LPSTR) "My Capture Window", // window name if pop-up

WS_CHILD | WS_VISIBLE, // window style

0, 0, 160, 120, // window position and dimensions

(HWND) hwndParent,

(int) nID /* child ID */);


2.連接到捕獲驅(qū)動(dòng)(Connecting to a Capture Driver)

           下面的例子是將MSVIDEO驅(qū)動(dòng)連接到句柄為hWndC的捕獲窗口, 然后調(diào)用capDriverDisconnect宏來(lái)斷接.

fOK = SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0, 0L);

//

// Or, use the macro to connect to the MSVIDEO driver:

// fOK = capDriverConnect(hWndC, 0);

//

// Place code to set up and capture video here.

//

capDriverDisconnect (hWndC);


3.列舉所有已安裝的捕獲驅(qū)動(dòng)(Enumerating Installed Capture Drivers)

           下面的例子使用capGetDriverDescription函數(shù)得到已安裝的捕獲驅(qū)動(dòng)的名稱及版本:

char szDeviceName[80];

char szDeviceVersion[80];


for (wIndex = 0; wIndex < 10; wIndex++)

{

if (capGetDriverDescription (wIndex, szDeviceName,

sizeof (szDeviceName), szDeviceVersion,

sizeof (szDeviceVersion))

{

// Append name to list of installed capture drivers

// and then let the user select a driver to use.

}

}


4.得到捕獲驅(qū)動(dòng)的性能(Obtaining the Capabilities of a Capture Driver)

              發(fā)送WM_CAP_DRIVER_GET_CAPS消息可以得到捕獲驅(qū)動(dòng)的性能,并保存入一個(gè)CAPDRIVERCAPS結(jié)構(gòu).每當(dāng)程序連接一個(gè)新的捕獲驅(qū)動(dòng)到一個(gè)捕獲窗口時(shí), 就應(yīng)該更新CAPDRIVERCAPS結(jié)構(gòu). 下面的程序舉例說(shuō)明了如何使用capDriverGetCaps宏來(lái)得到捕獲驅(qū)動(dòng)的性能:


CAPDRIVERCAPS CapDrvCaps;

SendMessage (hWndC, WM_CAP_DRIVER_GET_CAPS,

sizeof (CAPDRIVERCAPS), (LONG) (LPVOID) &CapDrvCaps);

// Or, use the macro to retrieve the driver capabilities.

// capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));


5.得到捕獲窗口的狀態(tài)(Obtaining the Status of a Capture Window)

                 下面的例子使用SetWindowPos函數(shù)使捕獲窗口與進(jìn)來(lái)的視頻流尺寸保持一致, 視頻流的基本信息是使用capGetStatus宏得到的, 保存在CAPSTATUS結(jié)構(gòu)中.


CAPSTATUS CapStatus;

capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth,

CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);


6.顯示對(duì)話框設(shè)置視頻特征(Displaying Dialog Boxes to Set Video Characteristics)

              每個(gè)視頻捕獲卡一般能提供三個(gè)不同的對(duì)話框用于控制視頻捕獲及數(shù)字化處理. 下面的例子說(shuō)明如何顯示這些對(duì)話框, 在顯示這些對(duì)話框之前,使用了capDriverGetCaps宏來(lái)檢查CAPDRIVERCAPS結(jié)構(gòu), 以檢測(cè)該卡是否有顯示這些對(duì)話框:


CAPDRIVERCAPS CapDrvCaps;

capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));


// Video source dialog box.

if (CapDriverCaps.fHasDlgVideoSource)

capDlgVideoSource(hWndC);


// Video format dialog box.

if (CapDriverCaps.fHasDlgVideoFormat)

{

capDlgVideoFormat(hWndC);

// Are there new image dimensions?

capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

// If so, notify the parent of a size change.

}


// Video display dialog box.

if (CapDriverCaps.fHasDlgVideoDisplay)

capDlgVideoDisplay(hWndC);


7.得到和設(shè)置視頻格式(Obtaining and Setting the Video Format)

                   BITMAPINFO結(jié)構(gòu)的長(zhǎng)度既適應(yīng)于標(biāo)準(zhǔn)的也適應(yīng)于壓縮的數(shù)據(jù)格式, 所有程序必須總是詢問(wèn)此結(jié)構(gòu)的尺寸以便在得到當(dāng)前的視頻格式之前分配內(nèi)存. 下面的例子就是使用capGetVideoFormatSize宏來(lái)得到緩沖區(qū)尺寸并調(diào)用capGetVideoFormat宏來(lái)得到當(dāng)前的視頻格式.


LPBITMAPINFO lpbi;

DWORD dwSize;

dwSize = capGetVideoFormatSize(hWndC);

lpbi = GlobalAllocPtr (GHND, dwSize);

capGetVideoFormat(hWndC, lpbi, dwSize);


// Access the video format and then free the allocated memory.


              程序可以使用capSetVideoFormat宏(或WM_CAP_SET_VIDEOFORMAT消息)發(fā)送一個(gè)BITMAPINFO頭結(jié)構(gòu)給捕獲窗口, 因?yàn)橐曨l格式是設(shè)備細(xì)節(jié), 你的程序應(yīng)該檢查返回值以便確定此格式是否已被接受.


8. 預(yù)覽視頻(Previewing Video)

             下面的例子使用capPreviewRate宏來(lái)設(shè)置每66毫秒顯示一幀, 并使用capPreview宏將它放置在捕獲窗口里.


capPreviewRate(hWndC, 66); // rate, in milliseconds

capPreview(hWndC, TRUE); // starts preview

// Preview

capPreview(hWnd, FALSE); // disables preview


9.將視頻設(shè)置為overlay模式(Enabling Video Overlay)

            下面的例子: capDriverGetCaps宏確定此捕獲卡是否有overlay功能, 如果有就使用宏來(lái)設(shè)置它


CAPDRIVERCAPS CapDrvCaps;

capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));


if (CapDrvCaps.fHasOverlay)

capOverlay(hWndC, TRUE);


10.命名捕獲文件(Naming the Capture File)

             下面的例子: 使用capFileSetCaptureFile宏來(lái)指定預(yù)備文件名為:MYCAP.AVI, capFileAlloc宏預(yù)先指定它的大小為5M.


char szCaptureFile[] = "MYCAP.AVI";

capFileSetCaptureFile( hWndC, szCaptureFile);

capFileAlloc( hWndC, (1024L * 1024L * 5));


11.格式化聲頻捕獲(Formatting Audio Capture)

             下面的例子使用capSetAudioFormat來(lái)設(shè)置聲頻格式為:11kHz, PCM 8位, 立體聲


WAVEFORMATEX wfex;

wfex.wFormatTag = WAVE_FORMAT_PCM;

wfex.nChannels = 2; // Use stereo

wfex.nSamplesPerSec = 11025;

wfex.nAvgBytesPerSec = 22050;

wfex.nBlockAlign = 2;

wfex.wBitsPerSample = 8;

wfex.cbSize = 0;


capSetAudioFormat(hWndC, &wfex, sizeof(WAVEFORMATEX));


12.改變視頻捕獲設(shè)置(Changing a Video Capture Setting)

               下面的例子使用capCaptureGetSetup和capCaptureSetSetup宏得將捕獲幀數(shù)從缺省的15幀改成每秒10幀.


CAPTUREPARMS CaptureParms;

float FramesPerSec = 10.0;


capCaptureGetSetup(hWndC, &CaptureParms, sizeof(CAPTUREPARMS));


CaptureParms.dwRequestMicroSecPerFrame = (DWORD) (1.0e6 /FramesPerSec);

capCaptureSetSetup(hWndC, &CaptureParms, sizeof (CAPTUREPARMS));


13.捕獲數(shù)據(jù)(Capturing Data)

                下面的例子使用capCaptureSequence宏來(lái)開(kāi)始捕獲視頻并使用capFileSaveAs宏來(lái)將捕獲的數(shù)據(jù)拷貝至NEWFILE.AVI文件中.


char szNewName[] = "NEWFILE.AVI";

// Set up the capture operation.

capCaptureSequence(hWndC);

// Capture.

capFileSaveAs(hWndC, szNewName);


14.增加一個(gè)信息塊(Adding an Information Chunk)

               如果你需要在你的程序捕獲的聲頻和視頻數(shù)據(jù)中加入你的其他信息, 你可以創(chuàng)建一個(gè)信息塊并將它們插入捕獲文件中, 信息塊可以包含一些典型的信息, 例如:版權(quán)信息,視頻來(lái)源, 外部定位信息等. 下面的例子使用capFileSetInfoChunk宏來(lái)插入一個(gè)信息塊, 里面包含了一個(gè)SMPTE的時(shí)間代碼.


// This example assumes the application controls

// the video source for preroll and postroll.

CAPINFOCHUNK cic;

// .

// .

// .

cic.fccInfoID = infotypeSMPTE_TIME;

cic.lpData = "00:20:30:12";

cic.cbData = strlen (cic.lpData) + 1;

capFileSetInfoChunk (hwndC, &cic);


15.在程序中加入一個(gè)回調(diào)函數(shù)(Adding Callback Functions to an Application)

               一個(gè)程序可以為捕獲窗口登記一個(gè)回調(diào)函數(shù)以便在以下的這些情況下通知程序.


狀態(tài)改變

錯(cuò)誤發(fā)生

視頻框架和聲頻緩沖區(qū)變得可用

程序應(yīng)用在捕獲視頻流的過(guò)程中接收


           下面的例子創(chuàng)建一個(gè)捕獲窗口并登記狀態(tài),錯(cuò)誤,視頻流和框架回調(diào)函數(shù)在消息處理對(duì)列中, 也包括了一個(gè)終止回調(diào)函數(shù)的說(shuō)明.


case WM_CREATE:

{

char achDeviceName[80]

char achDeviceVersion[100]

char achBuffer[100]

WORD wDriverCount = 0

WORD wIndex

WORD wError

HMENU hMenu


// Create a capture window using the capCreateCaptureWindow macro.

ghWndCap = capCreateCaptureWindow((LPSTR)"Capture Window",

WS_CHILD | WS_VISIBLE, 0, 0, 160, 120, (HWND) hWnd, (int) 0);


// Register the error callback function using the

// capSetCallbackOnError macro.

capSetCallbackOnError(ghWndCap, fpErrorCallback);


// Register the status callback function using the

// capSetCallbackOnStatus macro.

capSetCallbackOnStatus(ghWndCap, fpStatusCallback);


// Register the video-stream callback function using the

// capSetCallbackOnVideoStream macro.

capSetCallbackOnVideoStream(ghWndCap, fpVideoCallback);


// Register the frame callback function using the

// capSetCallbackOnFrame macro.

capSetCallbackOnFrame(ghWndCap, fpFrameCallback);


// Connect to a capture driver


break;

}

case WM_CLOSE:

{

// Use the capSetCallbackOnFrame macro to

// disable the frame callback. Similar calls exist for the other

// callback functions.


capSetCallbackOnFrame(hWndC, NULL);


break;

}


16.創(chuàng)建一個(gè)狀態(tài)回調(diào)函數(shù)(Creating a Status Callback Function)

            下面的例子是創(chuàng)建一個(gè)簡(jiǎn)單的狀態(tài)回調(diào)函數(shù),登記此回調(diào)函數(shù)使用capSetCallbackOnStatus宏.


// StatusCallbackProc: status callback function

// hWnd: capture window handle

// nID: status code for the current status

// lpStatusText: status text string for the current status

//

LRESULT PASCAL StatusCallbackProc(HWND hWnd, int nID,

LPSTR lpStatusText)

{

if (!ghWndMain)

return FALSE;


if (nID == 0) { // Clear old status messages.

SetWindowText(ghWndMain, (LPSTR) gachAppName);

return (LRESULT) TRUE;

}

// Show the status ID and status text...

wsprintf(gachBuffer, "Status# %d: %s", nID, lpStatusText);


SetWindowText(ghWndMain, (LPSTR)gachBuffer);

return (LRESULT) TRUE;

}


17.創(chuàng)建一個(gè)錯(cuò)誤回調(diào)函數(shù)( Creating an Error Callback Function)

             下面的例子是創(chuàng)建一個(gè)簡(jiǎn)單的錯(cuò)誤回調(diào)函數(shù),登記此回調(diào)函數(shù)使用capsetCallbackOnError宏:


// ErrorCallbackProc: error callback function

// hWnd: capture window handle

// nErrID: error code for the encountered error

// lpErrorText: error text string for the encountered error

//

LRESULT PASCAL ErrorCallbackProc(HWND hWnd, int nErrID,

LPSTR lpErrorText)

{

if (!ghWndMain)

return FALSE;


if (nErrID == 0) // Starting a new major function.

return TRUE; // Clear out old errors.


// Show the error identifier and text.

wsprintf(gachBuffer, "Error# %d", nErrID);


MessageBox(hWnd, lpErrorText, gachBuffer,

MB_OK | MB_ICONEXCLAMATION);


return (LRESULT) TRUE;

}


18.創(chuàng)建一個(gè)框架回調(diào)函數(shù)(Creating a Frame Callback Function)

              登記此回調(diào)函數(shù)使用capSetCallbackOnFrame宏:


// FrameCallbackProc: frame callback function

// hWnd: capture window handle

// lpVHdr: pointer to struct containing captured

// frame information

//

LRESULT PASCAL FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)

{

if (!ghWndMain)

return FALSE;


wsprintf(gachBuffer, "Preview frame# %ld ", gdwFrameNum++);

SetWindowText(ghWndMain, (LPSTR)gachBuffer);

return (LRESULT) TRUE

}


 

六.將四個(gè)標(biāo)準(zhǔn)對(duì)話框改成函數(shù)調(diào)用形式

              系統(tǒng)提供了四個(gè)標(biāo)準(zhǔn)的對(duì)話框:AudioFormat, VideoFormat, VideoSource, Video Compression,但有時(shí)程序希望通過(guò)函數(shù)控制它們,而不是使用系統(tǒng)提供的那個(gè)單一的對(duì)話框,此時(shí)就應(yīng)該使用函數(shù)調(diào)用的方法:


AudioFormat對(duì)話框

            可以通過(guò)使用capSetAudioFormat來(lái)實(shí)現(xiàn),此時(shí)要使用WAVEFORMATEX結(jié)構(gòu)。

例如:改成PCM格式,立體聲,16聲道,12.05kHz,則:

WAVEFORMATEX audioFormat;

// 確定寬度

acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT,&dwSize);

dwSize = max (dwSize, capGetAudioFormatSize (m_hwCapCapturing));

// 設(shè)置參數(shù)

audioFormat.wFormatTag = WAVE_FORMAT_PCM;

audioFormat.nChannels = 2;

audioFormat.nSamplesPerSec = 120500;

audioFormat.wBitsPerSample =16;

audioFormat.nBlockAlign = nBitsPerSample * nChannels / 8;

audioFormat.nAvgBytesPerSec =

audioFormat.nBlockAlign * nSamplesPerSec;

// 更新

capSetAudioFormat(ghCapWnd,&audioFormat,dwSize);

VideoFormat對(duì)話框

                  可以通過(guò)使用capSetVideoFormat來(lái)實(shí)現(xiàn),此時(shí)要使用BITMAPINFOHEADER結(jié)構(gòu)。

例如:設(shè)置圖片大小為RGB24位歲,大小為230X160

BITMAPINFOHEADER bi;

DWORD dwSize,dw;

bi.biSize = sizeof(BITMAPINFOHEADER);

bi.biWidth = 320; // 起作用

bi.biHeight = 160; // 起作用

bi.biPlanes = 1;

bi.biBitCount = 24;

bi.biCompression = BI_RGB;

bi.biSizeImage = 0;

bi.biXPelsPerMeter = 176;

bi.biYPelsPerMeter = 144;

bi.biClrUsed = 0;

bi.biClrImportant = 0;

dwSize = bi.biSize + ((bi.biBitCount > 8 || bi.biClrUsed) ? (bi.biClrUsed * sizeof(PALETTEENTRY)) : (2 ^ bi.biBitCount * sizeof(PALETTEENTRY)));

dw = capSetVideoFormat(m_hwCapCapturing, &bi, dwSize);

VideoSource對(duì)話框

                沒(méi)有找到現(xiàn)成的方法,但視頻捕獲卡提供的CD里面有一個(gè)動(dòng)態(tài)鏈接庫(kù)可以實(shí)現(xiàn)。

Video Compression對(duì)話框

             可以通過(guò)使用ICOpen,ICInfo等函數(shù)聯(lián)合起來(lái),得到當(dāng)前系統(tǒng)里面的視頻壓縮驅(qū)動(dòng)的列表,并可選擇其一,MSDN里面有一個(gè)程序示范了此用戶,程序名叫:ICWalk。

posted @ 2009-06-06 18:31 wrh 閱讀(3163) | 評(píng)論 (0)編輯 收藏

HWND   VFWAPI   capCreateCaptureWindow(  
      LPCSTR   lpszWindowName,      
      DWORD   dwStyle,                      
      int   x,                                      
      int   y,                                      
      int   nWidth,                            
      int   nHeight,                          
      HWND   hWnd,                              
      int   nID                                    
  );  
      Header:   Declared   in   vfw.h.  
      Import   Library:   Use   vfw32.lib.  
//////////////////////////////////////////////////////////////////////////////
調(diào)用capCreateCaptureWindow創(chuàng)建的窗口如何關(guān)閉釋放掉?
小弟不懂VC,只是調(diào)的API,用完后但不知道如何關(guān)閉掉這個(gè)窗口
網(wǎng)友回復(fù):HWND hWnd = capCreateCaptureWindow(...);

// 關(guān)閉該窗口
::SendMessage(hWnd, WM_CLOSE, 0, 0);

posted @ 2009-06-06 18:30 wrh 閱讀(2721) | 評(píng)論 (1)編輯 收藏
譯者:徐景周(原作:Alexander Mikula)

下載本文示例代碼

想要通過(guò)ODBC直接讀、寫(xiě)Excel表格文件,首先,應(yīng)確保ODBC中已安裝有Excel表格文件的驅(qū)動(dòng)"MICROSOFT EXCEL DRIVER (*.XLS)"。然后,可根據(jù)下面步驟進(jìn)行:

1. 在StdAfx.h文件中加入

#include <afxdb.h>
#include <odbcinst.h>
2. 通過(guò)ODBC直接創(chuàng)建Excel文件并在表中插入數(shù)據(jù)(暫定文件名:Demo.xls)
//創(chuàng)建并寫(xiě)入Excel文件
void CRWExcel::WriteToExcel()
{
CDatabase database;
CString sDriver = "MICROSOFT EXCEL DRIVER (*.XLS)"; // Excel安裝驅(qū)動(dòng)
CString sExcelFile = "c:\\demo.xls";                // 要建立的Excel文件
CString sSql;
TRY
{
// 創(chuàng)建進(jìn)行存取的字符串
sSql.Format("DRIVER={%s};DSN='''';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s",
sDriver, sExcelFile, sExcelFile);
// 創(chuàng)建數(shù)據(jù)庫(kù) (既Excel表格文件)
if( database.OpenEx(sSql,CDatabase::noOdbcDialog) )
{
// 創(chuàng)建表結(jié)構(gòu)(姓名、年齡)
sSql = "CREATE TABLE demo (Name TEXT,Age NUMBER)";
database.ExecuteSQL(sSql);
// 插入數(shù)值
sSql = "INSERT INTO demo (Name,Age) VALUES (''徐景周'',26)";
database.ExecuteSQL(sSql);
sSql = "INSERT INTO demo (Name,Age) VALUES (''徐志慧'',22)";
database.ExecuteSQL(sSql);
sSql = "INSERT INTO demo (Name,Age) VALUES (''郭徽'',27)";
database.ExecuteSQL(sSql);
}
// 關(guān)閉數(shù)據(jù)庫(kù)
database.Close();
}
CATCH_ALL(e)
{
TRACE1("Excel驅(qū)動(dòng)沒(méi)有安裝: %s",sDriver);
}
END_CATCH_ALL;
}
3. 通過(guò)ODBC直接讀取Excel文件(暫定文件名:Demo.xls)
// 讀取Excel文件
void CRWExcel::ReadFromExcel()
{
CDatabase database;
CString sSql;
CString sItem1, sItem2;
CString sDriver;
CString sDsn;
CString sFile = "Demo.xls"; 			// 將被讀取的Excel文件名
// 檢索是否安裝有Excel驅(qū)動(dòng) "Microsoft Excel Driver (*.xls)"
sDriver = GetExcelDriver();
if (sDriver.IsEmpty())
{
// 沒(méi)有發(fā)現(xiàn)Excel驅(qū)動(dòng)
AfxMessageBox("沒(méi)有安裝Excel驅(qū)動(dòng)!");
return;
}
// 創(chuàng)建進(jìn)行存取的字符串
sDsn.Format("ODBC;DRIVER={%s};DSN='''';DBQ=%s", sDriver, sFile);
TRY
{
// 打開(kāi)數(shù)據(jù)庫(kù)(既Excel文件)
database.Open(NULL, false, false, sDsn);
CRecordset recset(&database);
// 設(shè)置讀取的查詢語(yǔ)句.
sSql = "SELECT Name, Age "
"FROM demo "
"ORDER BY Name ";
// 執(zhí)行查詢語(yǔ)句
recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);
// 獲取查詢結(jié)果
while (!recset.IsEOF())
{
//讀取Excel內(nèi)部數(shù)值
recset.GetFieldValue("Name ", sItem1);
recset.GetFieldValue("Age", sItem2);
// 移到下一行
recset.MoveNext();
}
// 關(guān)閉數(shù)據(jù)庫(kù)
database.Close();
}
CATCH(CDBException, e)
{
// 數(shù)據(jù)庫(kù)操作產(chǎn)生異常時(shí)...
AfxMessageBox("數(shù)據(jù)庫(kù)錯(cuò)誤: " + e->m_strError);
}
END_CATCH;
}
4. 獲取ODBC中Excel驅(qū)動(dòng)的函數(shù)
CString CRWExcel::GetExcelDriver()
{
char szBuf[2001];
WORD cbBufMax = 2000;
WORD cbBufOut;
char *pszBuf = szBuf;
CString sDriver;
// 獲取已安裝驅(qū)動(dòng)的名稱(涵數(shù)在odbcinst.h里)
if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))
return "";
// 檢索已安裝的驅(qū)動(dòng)是否有Excel...
do
{
if (strstr(pszBuf, "Excel") != 0)
{
//發(fā)現(xiàn) !
sDriver = CString(pszBuf);
break;
}
pszBuf = strchr(pszBuf, ''\0'') + 1;
}
while (pszBuf[1] != ''\0'');
return sDriver;
}
作者信息:
姓名:徐景周(未來(lái)工作室 Future Studio)
EMAIL:jingzhou_xu@163.net

posted @ 2009-05-22 09:22 wrh 閱讀(1277) | 評(píng)論 (0)編輯 收藏

1.CString::IsEmpty

BOOL IsEmpty( ) const;

返回值:如果CString 對(duì)象的長(zhǎng)度為0,則返回非零值;否則返回0。

說(shuō)明:此成員函數(shù)用來(lái)測(cè)試一個(gè)CString 對(duì)象是否是空的。

示例:

下面的例子說(shuō)明了如何使用CString::IsEmpty。

// CString::IsEmpty 示例

CString s;

ASSERT( s.IsEmpty() );

請(qǐng)參閱 CString::GetLength

 

2.CString::Left

CString Left( int nCount ) const; 

throw( CMemoryException );

返回值:返回的字符串是前nCount個(gè)字符。

示例:

CString s( _T("abcdef") );

ASSERT( s.Left(2) == _T("ab") );

 

3.CString::LoadString

BOOL LoadString( UINT nID );

throw( CMemoryException );

返回值:如果加載資源成功則返回非零值;否則返回0。

nID  一個(gè)Windows 字符串資源ID。

說(shuō)明: 此成員函數(shù)用來(lái)讀取一個(gè)由nID 標(biāo)識(shí)的Windows 字符串資源,并放入一個(gè)已有CString 對(duì)象中。

示例:

下面的例子說(shuō)明了如何使用CString::LoadString。

// CString::LoadString 示例

#define IDS_FILENOTFOUND 1

CString s;

if (! s.LoadString( IDS_FILENOTFOUND ))

 

4.CString::MakeLower

void MakeLower( );  //改變字符的小寫(xiě)

 

5.CString::MakeReverse

void MakeReverse( );  //字符倒置

 

6.CString::MakeUpper

void MakeUpper( );  //改變字符的大寫(xiě)

 

7.CString::Mid CString Mid( int nFirst ) const; CString Mid( int nFirst, int nCount ) const; nCount代表要提取的字符數(shù), nFirst代表要提取的開(kāi)始索引位置

示例: CString s( _T("abcdef") ); ASSERT( s.Mid( 2, 3 ) == _T("cde") );

 

8.CString::ReleaseBuffer

void ReleaseBuffer( int nNewLength = -1 );

參數(shù):nNewLength

此字符串的以字符數(shù)表示的新長(zhǎng)度,不計(jì)算結(jié)尾的空字符。如果這個(gè)字

符串是以空字符結(jié)尾的,則參數(shù)的缺省值-1 將把CString 的大小設(shè)置為

字符串的當(dāng)前長(zhǎng)度。

說(shuō)明:

使用ReleaseBuffer 來(lái)結(jié)束對(duì)由GetBuffer 分配的緩沖區(qū)的使用。如果你知道緩

沖區(qū)中的字符串是以空字符結(jié)尾的,則可以省略nNewLength 參數(shù)。如果字符

串不是以空字符結(jié)尾的,則可以使用nNewLength 指定字符串的長(zhǎng)度。在調(diào)用

ReleaseBuffer 或其它CString 操作之后,由GetBuffer 返回的地址是無(wú)效的。

示例:

下面的例子說(shuō)明了如何使用CString::ReleaseBuffer。

// CString::ReleaseBuffer 示例

CString s;

s = "abc";

LPTSTR p = s.GetBuffer( 1024 );

strcpy(p, "abc"); // 直接使用該緩沖區(qū)

ASSERT( s.GetLength() == 3 ); // 字符串長(zhǎng)度 = 3

s.ReleaseBuffer(); // 釋放多余的內(nèi)存,現(xiàn)在p 無(wú)效。

ASSERT( s.GetLength() == 3 ); // 長(zhǎng)度仍然是3

 

9.CString::Remove

int CString::Remove ( TCHAR ch );

返回值:返回從字符串中移走的字符數(shù)。如果字符串沒(méi)有改變則返回零。

參數(shù):ch  要從一個(gè)字符串中移走的字符。

說(shuō)明:此成員函數(shù)用來(lái)將ch 實(shí)例從字符串中移走。與這個(gè)字符的比較是區(qū)分大小寫(xiě)

的。

示例:

// 從一個(gè)句子中移走小寫(xiě)字母'c':

CString str (“This is a test.”);

int n = str.Remove( 't' );

ASSERT( n == 2 );

ASSERT( str ==“This is a es. ” );

 10.CString::Replace

int Replace( TCHAR chOld, TCHAR chNew );

int Replace( LPCTSTR lpszOld, LPCTSTR lpszNew );

返回值:返回被替換的字符數(shù)。如果這個(gè)字符串沒(méi)有改變則返回零。

參數(shù):chOld     要被chNew 替換的字符。

chNew    要用來(lái)替換chOld 的字符。

lpszOld   一個(gè)指向字符串的指針,該字符串包含了要被lpszNew 替換的字符。

LpszNew  一個(gè)指向字符串的指針,該字符串包含了要用來(lái)替換lpszOld 的字符。

說(shuō)明:此成員函數(shù)用一個(gè)字符替換另一個(gè)字符。函數(shù)的第一個(gè)原形在字符串中用chNew

現(xiàn)場(chǎng)替換chOld。函數(shù)的第二個(gè)原形用lpszNew 指定的字符串替換lpszOld 指定

的子串。

在替換之后,該字符串有可能增長(zhǎng)或縮短;那是因?yàn)閘pszNew 和lpszOld 的長(zhǎng)度

不需要是相等的。兩種版本形式都進(jìn)行區(qū)分大小寫(xiě)的匹配。

示例:

// 第一個(gè)例子,old 和new 具有相同的長(zhǎng)度。

CString strZap( “C - -” );

int n = strZap.Replace('-', '+' );

ASSERT( n == 2 );

ASSERT(strZap == “C++” );

// 第二個(gè)例子,old 和new 具有不同的長(zhǎng)度。

CString strBang( “Everybody likes ice hockey” );

n = strBang.Replace( “hockey”, “golf” );

ASSERT( n ==1 );

n = strBang.Replace ( “likes” , “plays” );

ASSERT( n == 1 );

n = strBang.Replace( “ice”, NULL );

ASSERT( n == 1 );

ASSERT( strBang == “Everybody plays golg” );

// 注意,現(xiàn)在在你的句子中有了一個(gè)額外的空格。

// 要移走這個(gè)額外的空格,可以將它包括在要被替換的字符串中,例如,“ice ”。

 

11.CString::ReverseFind

int ReverseFind( TCHAR ch ) const;

返回值: 返回此CString 對(duì)象中與要求的字符匹配的最后一個(gè)字符的索引;如果沒(méi)有找

到需要的字符則返回-1。

參數(shù): ch  要搜索的字符。

說(shuō)明:此成員函數(shù)在此CString 對(duì)象中搜索與一個(gè)子串匹配的最后一個(gè)字符。此函數(shù)

類似于運(yùn)行時(shí)函數(shù)strrchr。

示例:

// CString::ReverseFind 示例

CString s( "abcabc" );

ASSERT( s.ReverseFind( 'b' ) == 4 );

 

12.CString::Right

CString Right( int nCount ) const; 

throw( CMemoryException );

返回值: 返回的字符串是最后nCount個(gè)字符。

CString s( _T("abcdef") );

ASSERT( s.Right(2) == _T("ef") );

 

13.CString:: SetAt

void SetAt( int nIndex, TCHAR ch );

 說(shuō)明:可以把字符串理解為一個(gè)數(shù)組,SetAt類似于[].注意nIndex的范圍,如果不合適會(huì)有調(diào)試錯(cuò)誤。 Ch 更替字符, 把nIndex位置上的字符 變成ch

 示例:

CString s( "abc" );

s.MakeReverse();

ASSERT( s == "cba" );

 

14.CString::TrimLeft

void TrimLeft( );

void CString::TrimLeft( TCHAR chTarget );

說(shuō)明:如果沒(méi)有參數(shù),從左刪除字符(\n\t空格等),至到遇到一個(gè)非此類字符. 當(dāng)然你也可以指定刪除那些字符. 如果指定的參數(shù)是字符串,那么遇上其中的一個(gè)字符就刪除. \n  換行符 \t  TAB字符

示例1: CString str = "\n\t a";

str.TrimLeft();

str為“a”;

 示例2:

CString str = "abbcadbabcadb ";

str.TrimLeft("ab");

結(jié)果"cadbabcadb "

str.TrimLeft("ac");

結(jié)果"bcadbabcadb "

 

15.CString::TrimRight

void TrimRight( );

void CString::TrimRight( TCHAR chTarget );

void CString::TrimRight( LPCTSTR lpszTargets );

說(shuō)明:用法類似于上面。

 

16.CString::Compare

int Compare( LPCTSTR lpsz ) const;

返回值:字符串一樣返回0,小于lpsz  返回-1,大于lpsz  返回1, 區(qū)分大小字符

示例:

CString s1( "abc" );

CString s2( "abd" );

ASSERT( s1.Compare( s2 ) == -1 );

ASSERT( s1.Compare( "abe" ) == -1 

17.CString::CompareNoCase

int CompareNoCase( LPCTSTR lpsz ) const;

返回值: 字符串一樣 返回0,小于lpsz  返回-1,大于lpsz  返回1,不區(qū)分大小字符

 

18.CString::Collate

int Collate( LPCTSTR lpsz ) const;

同CString::Compare

 

19.CString::CollateNoCase

int CollateNocase( LPCTSTR lpsz ) const;

同CString::CompareNoCase

 

20.CString::CString      //構(gòu)造函數(shù)

CString( );

CString( const CString& stringSrc ); 

CString( TCHAR ch, int nRepeat = 1 ); 

CString( LPCTSTR lpch, int nLength );

CString( const unsigned char* psz ); 

CString( LPCWSTR lpsz );

CString( LPCSTR lpsz );

示例:

CString s1;                     

CString s2( "cat" );              

CString s3 = s2;                 

CString s4( s2 + " " + s3 );        

CString s5( 'x' );                      // s5 = "x"

CString s6( 'x', 6 );                   // s6 = "xxxxxx"

CString s7((LPCSTR)ID_FILE_NEW);        // s7 = "Create a new document"

CString city = "Philadelphia";

 

21.CString::Delete

int Delete( int nIndex, int nCount = 1); 

返回值:是被刪除前的字符串的長(zhǎng)度

nIndex是第一個(gè)被刪除的字符,nCount是一次刪除幾個(gè)字符。根據(jù)我實(shí)驗(yàn)得出的結(jié)果:當(dāng)nCount>要?jiǎng)h除字符串的最大長(zhǎng)度(GetCount() - nIndex)時(shí)會(huì)出錯(cuò),當(dāng)nCount過(guò)大,沒(méi)有足夠的字符刪除時(shí),此函數(shù)不執(zhí)行。

示例:

CString str1,str2,str3;

char a;

str1 = "nihao";

str2 = "nIhao";

int x;

// int i=(str1 == str2);      

str1.Delete(2,3);

如果nCount(3) > GetCount() – nIndex (5-2)就會(huì)執(zhí)行錯(cuò)誤

 

22.CString::Empty

Void Empty( );

返回值:沒(méi)有返回值  清空操作;

示例:

CString s( "abc" );

s.Empty();

ASSERT( s.GetLength( ) == 0 );

 

23.CString::Find

int Find( TCHAR ch ) const;

int Find( LPCTSTR lpszSub ) const;

int Find( TCHAR ch, int nStart ) const;

int Find( LPCTSTR lpszSub, int nStart ) const;

返回值:  不匹配的話返回 -1;  索引以0 開(kāi)始; nStar 代表以索引值nStart 的字符開(kāi)始搜索 ,

即為包含以索引nStart字符后的字符串.

示例:

CString s( "abcdef" );

ASSERT( s.Find( 'c' ) == 2 );

ASSERT( s.Find( "de" ) == 3 );

Cstring str(“The stars are aligned”);

Ing n = str.Find('e',5);

ASSERT(n == 12)

 

24.CString::FindOneOf

int FindOneOf( LPCTSTR lpszCharSet ) const;

返回值:  不匹配的話返回 -1;  索引以0 開(kāi)始

注意::返回此字符串中第一個(gè)在lpszCharSet中也包括字符并且從零開(kāi)始的索引值

示例:

CString s( "abcdef" );

ASSERT( s.FindOneOf( "xd" ) == 3 ); // 'd' is first match.

 

25.CString::Format

void Format( LPCTSTR lpszFormat, ... );

void Format( UINT nFormatID, ... );

參數(shù):lpszFormat  一個(gè)格式控制字符串

nFormatID  字符串標(biāo)識(shí)符

示例:

CString str;

Str.Format(“%d”,13); 

此時(shí)Str為13

 

26.CString::GetAt

TCHAR GetAt( int nIndex ) const;

返回值:返回標(biāo)號(hào)為nIndex的字符,你可以把字符串理解為一個(gè)數(shù)組,GetAt類似于[].注意nIndex的范圍,如果不合適會(huì)有調(diào)試錯(cuò)誤。

 

27.CString::GetBuffer

LPTSTR GetBuffer( int nMinBufLength );

返回值:一個(gè)指向?qū)ο蟮模ㄒ钥兆址Y(jié)尾的)字符緩沖區(qū)的LPTSTR 指針。

參數(shù):nMinBufLength

字符緩沖區(qū)的以字符數(shù)表示的最小容量。這個(gè)值不包括一個(gè)結(jié)尾的空字符的空間。

說(shuō)明:此成員函數(shù)返回一個(gè)指向CString 對(duì)象的內(nèi)部字符緩沖區(qū)的指針。返回的LPTSTR 不是const,因此可以允許直接修改CString 的內(nèi)容。如果你使用由GetBuffer 返回的指針來(lái)改變字符串的內(nèi)容,你必須在使用其它的CString 成員函數(shù)之前調(diào)用ReleaseBuffer 函數(shù)。

在調(diào)用ReleaseBuffer 之后,由GetBuffer 返回的地址也許就無(wú)效了,因?yàn)槠渌腃String 操作可能會(huì)導(dǎo)致CString 緩沖區(qū)被重新分配。如果你沒(méi)有改變此CString 的長(zhǎng)度,則緩沖區(qū)不會(huì)被重新分配。當(dāng)此CString 對(duì)象被銷毀時(shí),其緩沖區(qū)內(nèi)存將被自動(dòng)釋放。

注意:如果你自己知道字符串的長(zhǎng)度,則你不應(yīng)該添加結(jié)尾的空字符。但是,當(dāng)你用ReleaseBuffer 來(lái)釋放該緩沖區(qū)時(shí),你必須指定最后的字符串長(zhǎng)度。如果你添加了結(jié)尾的空字符,你應(yīng)該給ReleaseBuffer 的長(zhǎng)度參數(shù)傳遞-1 ,ReleaseBuffer 將對(duì)該緩沖區(qū)執(zhí)行strlen 來(lái)確定它的長(zhǎng)度。

示例:

// CString::GetBuffer 例子

CString s( "abcd" );

#ifdef _DEBUG

afxDump << "CString s " << s << "\n";

#endif

LPTSTR p = s.GetBuffer( 10 );

strcpy( p, "Hello" ); // 直接訪問(wèn)CString 對(duì)象。

s.ReleaseBuffer( );

#ifdef _DEBUG

afxDump << "CString s " << s << "\n";

#endif

 

28.CString::GetLength

int GetLength( ) const;

返回值:返回字符串中的字節(jié)計(jì)數(shù)。

說(shuō)明:此成員函數(shù)用來(lái)獲取這個(gè)CString 對(duì)象中的字節(jié)計(jì)數(shù)。這個(gè)計(jì)數(shù)不包括結(jié)尾的空字符。

對(duì)于多字節(jié)字符集(MBCS),GetLength 按每一個(gè)8 位字符計(jì)數(shù);即,在一個(gè)多字節(jié)字符中的開(kāi)始和結(jié)尾字節(jié)被算作兩個(gè)字節(jié)。

示例

下面的例子說(shuō)明了如何使用CString::GetLength。

// CString::GetLength 示例

CString s( "abcdef" );

ASSERT( s.GetLength() == 6 );

 

29.CString::Insert

int Insert( int nIndex, TCHAR ch ); 

int Insert( int nIndex, LPCTSTR pstr );

返回值:返回修改后的長(zhǎng)度,nIndex是字符(或字符串)插入后的索引號(hào)例子

示例:

CString str( “HockeyBest”);

 int n = str.Insert( 6, “is” );

 ASSERT( n == str.GetLength( ) ); 

printf( “1: %s\n”, ( LPCTSTR ) str );

 n = str.Insert( 6, ' ' ); 

ASSERT( n == str.GetLength( ) ); 

printf ( “2: %s\n”, (LPCTSTR) STR );

 n = str.Insert(555, ‘1’);

ASSERT( n == str.GetLength ( ) );

 printf ( “3: %s\n”, ( LPCTSTR ) str );

輸出

1. Hockeyis Best

2. Hockey is Best

3. Hockey is Best!

posted @ 2009-05-22 09:19 wrh 閱讀(48227) | 評(píng)論 (0)編輯 收藏
在開(kāi)發(fā)軟件的過(guò)程里,經(jīng)常需要把數(shù)據(jù)保存到當(dāng)前執(zhí)行文件路徑下面,或者讀取當(dāng)前執(zhí)行文件路徑下的一些配置信息。這時(shí)就需要從當(dāng)前模塊里獲取所在的目錄路徑,以便進(jìn)行固定的位置操作文件。要解決這個(gè)需求,就需要調(diào)用API函數(shù)GetModuleFileName來(lái)獲取模塊所在的路徑。

函數(shù)GetModuleFileName聲明如下:
WINBASEAPI
DWORD
WINAPI
GetModuleFileNameA(
    __in_opt HMODULE hModule,
    __out_ecount_part(nSize, return + 1) LPCH lpFilename,
    __in    DWORD nSize
    );
WINBASEAPI
DWORD
WINAPI
GetModuleFileNameW(
    __in_opt HMODULE hModule,
    __out_ecount_part(nSize, return + 1) LPWCH lpFilename,
    __in    DWORD nSize
    );
#ifdef UNICODE
#define GetModuleFileName GetModuleFileNameW
#else
#define GetModuleFileName GetModuleFileNameA
#endif // !UNICODE
hModule是模塊的句柄,或者設(shè)置為NULL表示當(dāng)前模塊。
lpFilename是保存路徑的緩沖區(qū)。
nSize是緩沖區(qū)的大小。

調(diào)用函數(shù)的例子如下:
#001 //獲取當(dāng)前程序所在路徑。
#002  //蔡軍生 2007/12/05 QQ:9073204 深圳
#003  void TestGetExePath(void)
#004  {
#005        //
#006        const int nBufSize = 512;
#007        TCHAR chBuf[nBufSize];
#008        ZeroMemory(chBuf,nBufSize);
#009
#010        //獲取當(dāng)前執(zhí)行文件的路徑。
#011        if (GetModuleFileName(NULL,chBuf,nBufSize))
#012        {
#013              //輸出帶文件名稱路徑。
#014              OutputDebugString(chBuf);
#015              OutputDebugString(_T("\r\n"));
#016
#017              //獲取文件路徑。
#018              TCHAR* lpStrPath = chBuf;
#019              PathRemoveFileSpec(lpStrPath);
#020              OutputDebugString(lpStrPath);
#021              OutputDebugString(_T("\r\n"));
#022        }
#023
#024  }

輸出的結(jié)果如下:
g:\work\windows_api\wincpp2\debug\WinCpp.exe
g:\work\windows_api\wincpp2\debug
posted @ 2009-05-22 08:36 wrh 閱讀(471) | 評(píng)論 (0)編輯 收藏
GetModuleFileName是獲得程序當(dāng)前的運(yùn)行目錄
GetCurrentDirectory獲取當(dāng)前進(jìn)程所有在的目錄

復(fù)制代碼
  1.  CFileDialog fdlg(true);
  2.  fdlg.DoModal();//////
  3.  TCHAR *pBuffer = new TCHAR[1024];
  4.  ZeroMemory(pBuffer, 1024);
  5.  GetCurrentDirectory(1024, pBuffer);
  6.  MessageBox(pBuffer, L"GetCurrentDirectory");
  7.  ZeroMemory(pBuffer, 1024);
  8.  GetModuleFileName(NULL, pBuffer, 1024);
  9.  MessageBox(pBuffer, L"GetModuleFileName");

posted @ 2009-05-22 08:26 wrh 閱讀(876) | 評(píng)論 (0)編輯 收藏

下載本文示例代碼

想要通過(guò)ODBC直接讀、寫(xiě)Excel表格文件,首先,應(yīng)確保ODBC中已安裝有Excel表格文件的驅(qū)動(dòng)"MICROSOFT EXCEL DRIVER (*.XLS)"。然后,可根據(jù)下面步驟進(jìn)行:

1. 在StdAfx.h文件中加入:
#include <afxdb.h>

#include <odbcinst.h>

2. 通過(guò)ODBC直接創(chuàng)建Excel文件并在表中插入數(shù)據(jù)(暫定文件名:Demo.xls)
//創(chuàng)建并寫(xiě)入Excel文件

void CRWExcel::WriteToExcel()

{

  CDatabase database;

  CString sDriver = "MICROSOFT EXCEL DRIVER (*.XLS)"; // Excel安裝驅(qū)動(dòng)

  CString sExcelFile = "c:\\demo.xls";                // 要建立的Excel文件

  CString sSql;

   

  TRY

  {

    // 創(chuàng)建進(jìn)行存取的字符串

    sSql.Format("DRIVER={%s};DSN='''';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\"%s\";DBQ=%s",

                sDriver, sExcelFile, sExcelFile);

 

    // 創(chuàng)建數(shù)據(jù)庫(kù) (既Excel表格文件)

    if( database.OpenEx(sSql,CDatabase::noOdbcDialog) )

    {

      // 創(chuàng)建表結(jié)構(gòu)(姓名、年齡)

      sSql = "CREATE TABLE demo (Name TEXT,Age NUMBER)";

      database.ExecuteSQL(sSql);

 

      // 插入數(shù)值

      sSql = "INSERT INTO demo (Name,Age) VALUES (''徐景周'',26)";

      database.ExecuteSQL(sSql);

 

      sSql = "INSERT INTO demo (Name,Age) VALUES (''徐志慧'',22)";

      database.ExecuteSQL(sSql);

 

      sSql = "INSERT INTO demo (Name,Age) VALUES (''郭徽'',27)";

      database.ExecuteSQL(sSql);

    }     

 

    // 關(guān)閉數(shù)據(jù)庫(kù)

    database.Close();

  }

  CATCH_ALL(e)

  {

    TRACE1("Excel驅(qū)動(dòng)沒(méi)有安裝: %s",sDriver);

  }

  END_CATCH_ALL;

}

3. 通過(guò)ODBC直接讀取Excel文件(暫定文件名:Demo.xls)
// 讀取Excel文件

void CRWExcel::ReadFromExcel()

{

    CDatabase database;

    CString sSql;

    CString sItem1, sItem2;

    CString sDriver;

    CString sDsn;

    CString sFile = "Demo.xls";    // 將被讀取的Excel文件名

                                    

    // 檢索是否安裝有Excel驅(qū)動(dòng) "Microsoft Excel Driver (*.xls)"

    sDriver = GetExcelDriver();

    if (sDriver.IsEmpty())

    {

        // 沒(méi)有發(fā)現(xiàn)Excel驅(qū)動(dòng)

        AfxMessageBox("沒(méi)有安裝Excel驅(qū)動(dòng)!");

        return;

    }

   

    // 創(chuàng)建進(jìn)行存取的字符串

    sDsn.Format("ODBC;DRIVER={%s};DSN='''';DBQ=%s", sDriver, sFile);

 

    TRY

    {

        // 打開(kāi)數(shù)據(jù)庫(kù)(既Excel文件)

        database.Open(NULL, false, false, sDsn);

       

        CRecordset recset(&database);

 

        // 設(shè)置讀取的查詢語(yǔ)句.

        sSql = "SELECT Name, Age "      

               "FROM demo "                

               "ORDER BY Name ";

   

        // 執(zhí)行查詢語(yǔ)句

        recset.Open(CRecordset::forwardOnly, sSql, CRecordset::readOnly);

 

        // 獲取查詢結(jié)果

        while (!recset.IsEOF())

        {

            //讀取Excel內(nèi)部數(shù)值

            recset.GetFieldValue("Name ", sItem1);

            recset.GetFieldValue("Age", sItem2);

 

            // 移到下一行

            recset.MoveNext();

        }

 

        // 關(guān)閉數(shù)據(jù)庫(kù)

        database.Close();

                            

    }

    CATCH(CDBException, e)

    {

        // 數(shù)據(jù)庫(kù)操作產(chǎn)生異常時(shí)...

        AfxMessageBox("數(shù)據(jù)庫(kù)錯(cuò)誤: " + e->m_strError);

    }

    END_CATCH;

}

4. 獲取ODBC中Excel驅(qū)動(dòng)的函數(shù)
CString CRWExcel::GetExcelDriver()

{

    char szBuf[2001];

    WORD cbBufMax = 2000;

    WORD cbBufOut;

    char *pszBuf = szBuf;

    CString sDriver;

 

    // 獲取已安裝驅(qū)動(dòng)的名稱(涵數(shù)在odbcinst.h里)

    if (!SQLGetInstalledDrivers(szBuf, cbBufMax, &cbBufOut))

        return "";

   

    // 檢索已安裝的驅(qū)動(dòng)是否有Excel...

    do

    {

        if (strstr(pszBuf, "Excel") != 0)

        {

            //發(fā)現(xiàn) !

            sDriver = CString(pszBuf);

            break;

        }

        pszBuf = strchr(pszBuf, ''\0'') + 1;

    }

    while (pszBuf[1] != ''\0'');

 

    return sDriver;

}

作者信息:
姓名:徐景周(未來(lái)工作室 Future Studio)
EMAIL:jingzhou_xu@163.net

本文來(lái)自: 乘風(fēng)原創(chuàng)程序(http://www.qqcf.com) 詳細(xì)出處參考:http://study.qqcf.com/web/197/22219.htm

posted @ 2009-05-21 21:25 wrh 閱讀(893) | 評(píng)論 (0)編輯 收藏

一、 VC 提供的數(shù)據(jù)庫(kù)訪問(wèn)技術(shù)

ODBC API MFC ODBC DAO OLE DB ADO

訪問(wèn)速度:傳統(tǒng)的 ODBC 速度較慢。 OLE DB ADO 都是基于 COM 技術(shù),使用該技術(shù)可以直接訪問(wèn)數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序,速度大大提高。

 

可擴(kuò)展性:通過(guò) OLE DB ActiveX 技術(shù),可以利用 VC 提供的各種組件,控件和第三方提供的組建。從而實(shí)現(xiàn)應(yīng)用程序組件化。

 

訪問(wèn)不同數(shù)據(jù)源:傳統(tǒng) ODBC 只能訪問(wèn)關(guān)系數(shù)據(jù)庫(kù)。 VC 中提供 OLD DB 技術(shù)可以解決該問(wèn)題。

二、 幾種技術(shù)概述

1、 ODBC API

提供一個(gè)通用接口,為 ORACLE SQLSERVER 都提供了驅(qū)動(dòng)程序。用戶可以 SQL 語(yǔ)句對(duì)數(shù)據(jù)庫(kù)進(jìn)行直接的底層功能操作。使用時(shí)應(yīng)包含以下頭文件。 ”SQL.H”,”SQLEXT.H”,”SQLTYPES.H”.

使用步驟如下:

第一步:分配 ODBC 環(huán)境,初始化一些內(nèi)部結(jié)構(gòu)。完成該步,需要分配一個(gè) SQLHENV 類型的變量在 ODBC 環(huán)境中做句柄使用。

第二步:為將要使用的每一個(gè)數(shù)據(jù)源分配一個(gè)連接句柄,有函數(shù) SQLALLocHandle ()完成。

第三步:使用 SQLConnect ()把連接句柄與數(shù)據(jù)庫(kù)連接,可以先通過(guò) SQLSetConnectAttr ()設(shè)置連接屬性。

第四步:進(jìn)行 SQL 語(yǔ)句操作。操作完就可以斷開(kāi)與數(shù)據(jù)庫(kù)的連接。

第五步:釋放 ODBC 環(huán)境。

 

特點(diǎn):功能強(qiáng)大,提供異步操作,事務(wù)處理等高級(jí)功能。目前所有關(guān)系數(shù)據(jù)庫(kù)都提供了 ODBC 的驅(qū)動(dòng)程序,使用很廣泛。

缺點(diǎn):很難訪問(wèn)對(duì)象數(shù)據(jù)庫(kù)和非關(guān)系數(shù)據(jù)庫(kù)。

 

2、 MFC ODBC

 

為簡(jiǎn)化使用 ODBC API VC 提供了 MFC ODBC 類,封裝了 ODBC API

主要 MFC ODBC 類如下:

CDatabase 類:一個(gè) CDatabase 對(duì)象表示一個(gè)到數(shù)據(jù)源的連接,通過(guò)它可以操作數(shù)據(jù)源。一般不需要直接使用 CDatabase 對(duì)象,因?yàn)?/span> CDecordSet 對(duì)象可以實(shí)現(xiàn)大多數(shù)功能,但在進(jìn)行事務(wù)處理時(shí), CDatabase 就起到關(guān)鍵作用。

CRecordSet 類:一個(gè) CRecordSet 對(duì)象代表一個(gè)從數(shù)據(jù)源選擇的一組記錄的集合 ----- 記錄集。記錄集有兩種形式: snapshot dynaset 。前者表示是靜態(tài)視圖。后者表示記錄集與其它用戶對(duì)數(shù)據(jù)庫(kù)的更新保持同步。

CRecordView 類:是在空間中顯示數(shù)據(jù)庫(kù)記錄的視圖。這種視圖是直接連到一個(gè) CRecordSet 對(duì)象的格式視圖。他從一個(gè)對(duì)話框模版資源創(chuàng)建。并將 CRecordSet 對(duì)象的字段顯示在對(duì)話框模版的控件里。對(duì)象利用 DDX RFX 機(jī)制。使格式上的控件和記錄集的字段之間數(shù)據(jù)移動(dòng)自動(dòng)化。

CDBException 類:由 Cexception 類派生,以 3 個(gè)繼承的變量反映對(duì)數(shù)據(jù)庫(kù)操作時(shí)的異常。

 M_nRetCode: ODBC 返回碼。

M_strError: 字符串,描述造成拋出異常的錯(cuò)誤原因。

M_strStateNativeOrigin: 字符串,描述以 ODBC 錯(cuò)誤碼表示的異常錯(cuò)誤。

 

3、 MFC DAO

 

MFC DAO 是微軟提供的用于訪問(wèn) Microsoft Jet 數(shù)據(jù)庫(kù)文件( * Mdb )的工具。當(dāng)只需訪問(wèn) Access 數(shù)據(jù)庫(kù)時(shí)用該技術(shù)很方便。

4、 OLE DB

 

ODBC 技術(shù)類似, OLE DB 屬于數(shù)據(jù)庫(kù)訪問(wèn)技術(shù)中的底層接口。

直接使用 OLEDB 需要大量代碼, VC 中提供了 ATL 模版,

OLEDB 框架定義了應(yīng)用的 3 個(gè)基本類。

 

數(shù)據(jù)提供程序 Data Provider 擁有自己的數(shù)據(jù)并以表格形式顯示數(shù)據(jù)的應(yīng)用程序。

使用者 Consumers :試用 OLEDB 接口對(duì)存儲(chǔ)在數(shù)據(jù)提供程序中對(duì)數(shù)據(jù)進(jìn)行控制的應(yīng)用程序。

服務(wù)提供程序 ServiceProvider :是數(shù)據(jù)提供程序和使用者的組合。

 

使用 OLE DB 編程時(shí),用戶使用組件對(duì)象開(kāi)發(fā)程序,這些組件包括:

枚舉器:用于列出可用的數(shù)據(jù)源;

數(shù)據(jù)源:代表單獨(dú)的數(shù)據(jù)和服務(wù)提供程序,用于創(chuàng)建對(duì)話;

對(duì)話:     用于創(chuàng)建事務(wù)和命令;

事務(wù):     用于將多個(gè)操作歸并為單一事務(wù)處理;

命令:     用于向數(shù)據(jù)源發(fā)送文本命令( SQL ),返回行集;

錯(cuò)誤:     用于獲得錯(cuò)誤信息。

5、 ADO

 

ADO 技術(shù)是基于 OLE DB 的訪問(wèn)接口。繼承了 OLEDB 的優(yōu)點(diǎn),并對(duì) OLEDB 的接口作了封裝,定義了 ADO 對(duì)象,使開(kāi)發(fā)簡(jiǎn)化。 ADO 屬于數(shù)據(jù)庫(kù)訪問(wèn)的高層接口。

 

ADO 在服務(wù)器應(yīng)用方面非常有效,特別是動(dòng)態(tài)服務(wù)器頁(yè)面( ASP )的支持。

 

ADO 對(duì)象結(jié)構(gòu)類似于 OLEDB ,但并不依靠對(duì)象層次。大多數(shù)情況用戶只需創(chuàng)建并使用需要的對(duì)象。下面的對(duì)象類組成了 ADO 接口。

 

Connection  用于表示與數(shù)據(jù)庫(kù)的連接,以及處理一些事務(wù)和命令。

Command    用于處理傳送給數(shù)據(jù)源的命令。

Recordset    用于處理數(shù)據(jù)的表格集, 包括獲取和修改數(shù)據(jù)。

Field            用于表示記錄集中的列信息,包括列值和其他信息。

Parameter    在傳送給數(shù)據(jù)源的命令之間傳遞數(shù)據(jù)。

Property      用于操作在 ADO 中使用的其它對(duì)象的詳細(xì)屬性。

Errro           用于獲取可能發(fā)生的詳細(xì)錯(cuò)誤信息

posted @ 2009-05-21 21:18 wrh 閱讀(404) | 評(píng)論 (0)編輯 收藏
使用VC編程來(lái)操縱Office。你可以實(shí)現(xiàn)諸如:Word文件打印、傳送數(shù)據(jù)到Word文檔、發(fā)送E-MAIL、自動(dòng)產(chǎn)生表格、Excel數(shù)據(jù)統(tǒng)計(jì)、圓餅圖,直方圖顯示、自動(dòng)報(bào)表生成、播放幻燈、doc,txt,HTML,rtf文件轉(zhuǎn)換、中文簡(jiǎn)繁體轉(zhuǎn)換、拼音或筆畫(huà)排序......只要是Office能夠?qū)崿F(xiàn)的功能,都可以在你寫(xiě)的程序中調(diào)用。仔細(xì)閱讀下面的說(shuō)明,并下載源文件進(jìn)行參考,你就可以一步一步地掌握這個(gè)技術(shù)。祝朋友們學(xué)習(xí)快樂(lè)。

  一、概念

  Microsoft 的 Office 產(chǎn)品中,都提供了OLE Automation 自動(dòng)化程序的接口。如果你使用VB,VBA 和 Script 腳本調(diào)用 Office 功能的話,其實(shí)比使用 VC 調(diào)用要簡(jiǎn)單的多。比如在 WORD 中,調(diào)出菜單“工具(T)\宏(M)\錄制新宏(R)”,這時(shí)候它開(kāi)始記錄你在 WORD 中任何菜單和鍵盤(pán)的操作,把你的操作過(guò)程保存起來(lái),以便再次重復(fù)調(diào)用。而保存這些操作的記錄,其實(shí)就是使用了 VBA 程序(Visual Basic for Application)。而我們下面要實(shí)現(xiàn)的功能,也同樣要參考 VBA 的方法。

  二、結(jié)構(gòu)層次

  為了更有邏輯,更有層次地操作 Office,Microsoft 把應(yīng)用(Application)按邏輯功能劃分為如下的樹(shù)形結(jié)構(gòu)

Application(WORD 為例,只列出一部分)
Documents(所有的文檔)
Document(一個(gè)文檔)
......
  Templates(所有模板)
Template(一個(gè)模板)
......
  Windows(所有窗口)
Window
Selection
View
Selection(編輯對(duì)象)
Font
Style
Range
......
......

  只有了解了邏輯層次,我們才能正確的操縱 Office。舉例來(lái)講,如果給出一個(gè)VBScript語(yǔ)句是:
application.ActiveDocument.SaveAs "c:\abc.doc"

  那么,我們就知道了,這個(gè)操作的過(guò)程是:第一步,取得Application;第二步,從Application中取得ActiveDocument;第三步,調(diào)用 Document 的函數(shù) SaveAs,參數(shù)是一個(gè)字符串型的文件名。
三、基本步驟

  (1)創(chuàng)建(或打開(kāi)已有的)一個(gè) MFC 的程序工程

  (2)Ctrl+W 執(zhí)行 ClassWizard(本文按照 VC6 操作,例子程序也是在VC6 下編寫(xiě)測(cè)試的)

  (3)Add Class...\From a type Library... 在 Office 目錄中,找到你想使用的類型庫(kù)。(我使用的是 Office2000,其Word 的類型庫(kù)文件,保存在 C:\Program Files\Microsoft Office\Office\MSWORD9.OLB)根據(jù)你 Office 的版本,可以使用下表列出的類型庫(kù)文件

Office 版本和類型 類型庫(kù)文件 Office 版本和類型 類型庫(kù)文件
Access 97 Msacc8.olb PowerPoint 2000 Msppt9.olb
Jet Database 3.5 DAO350.dll Word 2000 Msword9.olb
Binder 97 Msbdr8.olb Access 2002 Msacc.olb
Excel 97 Excel8.olb Excel 2002 Excel.exe
Graph 97 Graph8.olb Graph 2002 Graph.exe
Office 97 Mso97.dll Office 2002 MSO.dll
Outlook 97 Msoutl97.olb Outlook 2002 MSOutl.olb
PowerPoint 97 Msppt8.olb PowerPoint 2002 MSPpt.olb
Word 97 Msword8.olb Word 2002 MSWord.olb
Access 2000 Msacc9.olb Office Access 2003 Msacc.olb
Jet Database 3.51 DAO360.dll Office Excel 2003 Excel.exe
Binder 2000 Msbdr9.olb Graph 2003 Graph.exe
Excel 2000 Excel9.olb Office 2003 MSO.dll
Graph 2000 Graph9.olb Office Outlook 2003 MSOutl.olb
Office 2000 Mso9.dll Office PowerPoint 2003 MSPpt.olb
Outlook 2000 Msoutl9.olb Office Word 2003 MSWord.olb

  (4)選擇類型庫(kù)文件后,在彈出的對(duì)話窗中繼續(xù)選擇要添加的類。具體選擇什么類,要看你將來(lái)在程序中打算調(diào)用什么功能。當(dāng)然,你也可以不用考慮這么多,用鼠標(biāo)和Shift鍵配合,全部選擇也可以。

  (5)初始化COM。方法一,找到App的InitInstance()函數(shù),在其中添加 AfxOleInit()函數(shù)的調(diào)用;方法二,在需要調(diào)用COM功能的地方 CoInitialize(NULL),調(diào)用完畢后 CoUninitialize()。

  (6)在你需要調(diào)用 Office 功能函數(shù)的 cpp 文件中

#include <atlbase.h> // 為了方便操作 VARIANT 類型變量,使用 CComVariant 模板類
#include "頭文件.h"
// 具體的頭文件名,是由裝載類型庫(kù)的文件名決定的。(鼠標(biāo)雙點(diǎn)包裝類的文件,就可以看到)
// 比如使用 msword9.olb類型庫(kù),那么頭文件是 msword9.h

  (7)好了,現(xiàn)在開(kāi)始寫(xiě)程序吧。另外要說(shuō)明的是,步驟3和4,其實(shí)也可以使用 #import 方式引入類型庫(kù)。

  四、實(shí)現(xiàn)技巧

  在書(shū)寫(xiě)調(diào)用 Office 函數(shù)的過(guò)程中,最困難的是確定函數(shù)的參數(shù),一般情況下,參數(shù)都是 VARIANT 類型的變量指針。那么到底具體我們應(yīng)該怎么寫(xiě)那?推薦兩個(gè)方法,其一是閱讀有關(guān) VBA 的書(shū)籍;其二,是使用 Office 中自帶的“宏”功能。強(qiáng)烈推薦大家使用第二個(gè)方法,把你要完成的功能,在 Office 的操作環(huán)境中,用宏錄制下來(lái),然后觀察分析錄制后的函數(shù)和參數(shù),就可以在 VC 中使用了。舉一個(gè)例子:

ActiveDocument.SaveAs FileName:="Hello.doc", FileFormat:=wdFormatDocument _
, LockComments:=False, Password:="", AddToRecentFiles:=True, _
WritePassword:="", ReadOnlyRecommended:=False, EmbedTrueTypeFonts:=False, _
SaveNativePictureFormat:=False, SaveFormsData:=False, SaveAsAOCELetter:= _
False

  以上是在 Word 中錄制的一個(gè)保存文件的宏,而在 VC 中對(duì)應(yīng)的函數(shù)原型為 void _Document::SaveAs(VARIANT* FileName, VARIANT* FileFormat, VARIANT* LockComments,
VARIANT* Password, VARIANT* AddToRecentFiles, VARIANT* WritePassword,
VARIANT* ReadOnlyRecommended, VARIANT* EmbedTrueTypeFonts, VARIANT* SaveNativePictureFormat,
VARIANT* SaveFormsData, VARIANT* SaveAsAOCELetter)

  分析對(duì)照后,我們就能看出,參數(shù) FileName 是字符串 VARIANT(VT_BSTR),參數(shù) LockComments 是布爾VARIANT(VT_BOOL),等等。參數(shù) FileFormat := wdFormatDocument 是什么類型那?其實(shí)這是一個(gè)表示保存的時(shí)候指定文件類型的常量,而且顯然是 DWORD 類型VARIANT(VT_I4)。那么常量的數(shù)值又是多少那?很簡(jiǎn)單,寫(xiě)一個(gè)宏,調(diào)用函數(shù) MsgBox 顯示一下不就都知道啦?!

  五、步步為營(yíng)

  特別提示一:編譯執(zhí)行前,一定要先關(guān)閉 KV 實(shí)時(shí)監(jiān)視病毒的功能(KV 的程序會(huì)干擾我們的調(diào)用,瑞星的則沒(méi)關(guān)系)。

   特別提示二:在例子程序中,為了表現(xiàn)程序的關(guān)鍵部分,沒(méi)有或很少使用了條件判斷。為了實(shí)現(xiàn)你程序的健壯性,請(qǐng)自己加上條件判斷和異常處理。

  Step1:如何啟動(dòng)和關(guān)閉 WORD,及 VARIANT 的最基本的使用方法
  Step2:和 Step1 同樣功能,用 CComVariant 改進(jìn)了 VARIANT 的使用方式
  Step3:在 Step2 的基礎(chǔ)上,新建一個(gè) WORD 文檔,并從程序中傳送一些字符到 WORD
  Step4:在 Step3 的基礎(chǔ)上,保存 WORD 文檔
  Step5:一個(gè)小應(yīng)用舉例,把輸入的漢字按照“筆畫(huà)”排序
  Step6:一個(gè)小應(yīng)用舉例,盜竊正在使用的 WORD 文檔

  以上這6個(gè)小程序中,都有詳細(xì)的注釋。大家閱讀后慢慢體會(huì)并實(shí)驗(yàn),你就可以自由地操縱任何一個(gè) Office 啦。

  源代碼下載

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

導(dǎo)航

<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

統(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>
            亚洲精品影院| 一区二区三区自拍| 免费欧美日韩| 久久尤物电影视频在线观看| 久久国产综合精品| 久久久精品免费视频| 久久一区欧美| 欧美激情一区二区三区在线视频观看 | 日韩视频在线免费观看| 日韩午夜精品| 亚洲午夜激情| 欧美一区二区女人| 卡一卡二国产精品| 欧美激情一区二区三区高清视频| 欧美日韩国产一级| 国产欧美日韩| 影音先锋中文字幕一区| 亚洲毛片在线| 羞羞漫画18久久大片| 久久激情视频久久| 欧美成人免费全部| 亚洲狼人精品一区二区三区| 亚洲影院一区| 美女视频一区免费观看| 欧美视频网址| 狠狠色香婷婷久久亚洲精品| 亚洲毛片在线| 久久久av网站| 亚洲精品久久久久中文字幕欢迎你| 亚洲电影第三页| 亚洲一区二区三区四区中文| 久久免费国产精品| 国产精品av久久久久久麻豆网| 狠狠狠色丁香婷婷综合激情| 一个色综合av| 久久综合激情| 在线亚洲精品| 猛干欧美女孩| 国产精品永久入口久久久| 亚洲国产精品黑人久久久| 亚洲欧美国产三级| 欧美韩国日本一区| 亚洲欧美另类久久久精品2019| 免费久久精品视频| 国产日韩精品一区| 99精品国产在热久久婷婷| 久久精品国产99| 亚洲人体偷拍| 久久久久国产一区二区三区| 欧美日韩在线第一页| 尤物九九久久国产精品的分类| 亚洲综合精品四区| 亚洲黄色成人网| 欧美在线观看一区二区三区| 欧美特黄一级大片| 亚洲国产精品久久久久| 欧美在线黄色| 久久久久久亚洲精品不卡4k岛国| 久久久久成人精品| 日韩一区二区精品| 久久久水蜜桃| 国产精品视频网址| 99热在线精品观看| 美女免费视频一区| 亚洲女同性videos| 欧美日韩一二三区| 亚洲精品在线视频观看| 美女主播一区| 欧美在线播放一区| 国产伦精品一区二区三区| 亚洲视频免费观看| 亚洲精品1区2区| 免费不卡在线观看av| 精品1区2区3区4区| 久久精品国产视频| 亚洲在线观看免费视频| 欧美午夜激情在线| 亚洲黄色性网站| 麻豆免费精品视频| 久久精品国产久精国产爱| 国产精品一级二级三级| 亚洲一区三区视频在线观看| 亚洲精品一区二区三区福利| 欧美大片va欧美在线播放| 亚洲第一主播视频| 欧美99在线视频观看| 久久午夜激情| 亚洲国产高清一区二区三区| 免费高清在线一区| 久久久久久一区| 亚洲第一在线| 亚洲国产精品久久| 欧美国产日韩xxxxx| 亚洲日本久久| 亚洲国产免费| 欧美精品情趣视频| 亚洲精选一区| 亚洲人成人一区二区在线观看| 欧美大成色www永久网站婷| 亚洲精品日韩在线观看| 亚洲国产日韩欧美| 欧美精品日韩综合在线| 一本到高清视频免费精品| 91久久中文| 欧美日韩国产在线| 亚洲综合成人婷婷小说| 亚洲一区视频在线| 国产日韩欧美自拍| 久久婷婷麻豆| 免费观看成人鲁鲁鲁鲁鲁视频| 亚洲日韩欧美视频一区| 日韩视频欧美视频| 国产精品美女久久久浪潮软件 | 亚洲免费视频在线观看| 亚洲一区二区三区精品在线| 国产免费成人在线视频| 久久免费国产精品| 久久夜色精品国产欧美乱极品| 亚洲人成免费| 一本色道久久综合亚洲精品按摩| 国产精品久久久久免费a∨大胸| 欧美一区二区三区在线观看| 欧美一区二区三区免费观看视频| 一区二区三区在线免费播放| 亚洲高清毛片| 欧美性一二三区| 久久精品视频网| 美日韩精品视频| 亚洲一区在线播放| 欧美一区二区三区四区在线观看地址| 在线观看精品一区| 亚洲第一毛片| 国产精品成人av性教育| 久久久91精品国产一区二区三区| 免费黄网站欧美| 亚洲欧美影院| 欧美在线一级va免费观看| 亚洲黄色影院| 亚洲一区二区三区高清| 在线观看国产精品淫| 一本色道精品久久一区二区三区| 国产日韩欧美在线播放| 亚洲福利在线视频| 国产精品无码永久免费888| 欧美91视频| 国产精品永久入口久久久| 欧美韩日精品| 国产日韩欧美在线观看| 亚洲欧洲在线播放| 国产一区二区精品丝袜| 亚洲国产免费看| 国产性猛交xxxx免费看久久| 亚洲国产裸拍裸体视频在线观看乱了中文 | 久久夜色精品国产噜噜av| 亚洲调教视频在线观看| 欧美日韩国产影院| 一本色道久久综合亚洲精品高清| 欧美激情国产精品| 美女日韩在线中文字幕| 亚洲国产精品热久久| 欧美1区2区视频| 久久综合99re88久久爱| 亚洲高清电影| 欧美韩日精品| 欧美巨乳在线| 中文精品视频| 正在播放亚洲| 国产乱肥老妇国产一区二 | 久久亚洲一区二区| 激情综合色丁香一区二区| 久久精品国产久精国产爱| 欧美一进一出视频| 国内精品99| 免费观看不卡av| 欧美大片在线看| 亚洲视频在线观看三级| 亚洲视频在线视频| 国产一区二区福利| 欧美波霸影院| 欧美精品一区三区在线观看| 在线一区视频| 亚洲一区二区三区国产| 国产一区二区三区成人欧美日韩在线观看 | 亚洲最新视频在线| 国产精品久久精品日日| 欧美一区二区三区久久精品 | 久久爱另类一区二区小说| 黑人操亚洲美女惩罚| 农夫在线精品视频免费观看| 欧美成人免费全部| 亚洲欧美激情视频| 欧美中文字幕| 亚洲精品久久久久久下一站| 日韩一级视频免费观看在线| 国产精品五区| 免费欧美日韩国产三级电影| 欧美精品国产精品| 欧美中文字幕不卡| 麻豆精品传媒视频| 亚洲一区二区三区午夜|