• <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>

             
            函數名:

             

              SetWindowPos

            頭文件:

              winuser.h

            函數原型:

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

            說明:

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

              BOOL,如果返回值非零表示成功,返回零表示失敗。錯誤信息請參看GetLastError函數。

            參數表:

              參數 類型及說明
              hwnd HWND,欲定位的窗口句柄
              hWndInsertAfter HWND,置于hwnd前面的窗口句柄。這個參數必須是窗口的句柄或是下面的值之一:    HWND_BOTTOM 將窗口置于其它所有窗口的底部
              HWND_NOTOPMOST 將窗口置于其它所有窗口的頂部,并位于任何最頂部窗口的后面。如果這個窗口非頂部窗口,這個標記對該窗口并不產生影響
              HWND_TOP 將窗口置于它所有窗口的頂部
              HWND_TOPMOST 將窗口置于其它所有窗口的頂部,并位于任何最頂部窗口的前面。即使這個窗口不是活動窗口,也維持最頂部狀態

            x: 
             
              int,指定窗口新的X坐標

            Y:  

              int,指定窗口新的Y坐標

            cx:  

              int,指定窗口新的寬度

            cy:  

              int,指定窗口新的高度

            wFlags:

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


            備注:

              如果設置了SWP_SHOWWINDOW或SWP_HIDEWINDOW標記,這個窗口不發生移動或改變大小。窗口成為最頂級窗口后,它的所有子窗口也會進入最頂級。一旦將其設為非最頂級,則它的所有子窗口也會轉為非最頂級。

            相關函數:

              MoveWindow,SetActiveWindow,SetForegroundWindow

            例子:

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

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

            函數功能:該函數改變一個子窗口,彈出式窗口式頂層窗口的尺寸,位置和Z序。子窗口,彈出式窗口,及頂層窗口根據它們在屏幕上出現的順序排序、頂層窗口設置的級別最高,并且被設置為Z序的第一個窗口。

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

                 參數:

                 hWnd:窗口句柄。

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

                 HWND_BOTTOM:將窗口置于Z序的底部。如果參數hWnd標識了一個頂層窗口,則窗口失去頂級位置,并且被置在其他窗口的底部。

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

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

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

                 查g看該參數的使用方法,請看說明部分。

                 x:以客戶坐標指定窗口新位置的左邊界。

                 Y:以客戶坐標指定窗口新位置的頂邊界。

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

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

                 uFlags:窗口尺寸和定位的標志。該參數可以是下列值的組合:

                 SWP_ASNCWINDOWPOS:如果調用進程不擁有窗口,系統會向擁有窗口的線程發出需求。這就防止調用線程在其他線程處理需求的時候發生死鎖。

                 SWP_DEFERERASE:防止產生WM_SYNCPAINT消息。

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

                 SWP_FRAMECHANGED:給窗口發送WM_NCCALCSIZE消息,即使窗口尺寸沒有改變也會發送該消息。如果未指定這個標志,只有在改變了窗口尺寸時才發送WM_NCCALCSIZE。

                 SWP_HIDEWINDOW;隱藏窗口。

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

                 SWP_NOCOPYBITS:清除客戶區的所有內容。如果未設置該標志,客戶區的有效內容被保存并且在窗口尺寸更新和重定位后拷貝回客戶區。

                 SWP_NOMOVE:維持當前位置(忽略X和Y參數)。

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

                 SWP_NOREDRAW:不重畫改變的內容。如果設置了這個標志,則不發生任何重畫動作。適用于客戶區和非客戶區(包括標題欄和滾動條)和任何由于窗回移動而露出的父窗口的所有部分。如果設置了這個標志,應用程序必須明確地使窗口無效并區重畫窗口的任何部分和父窗口需要重畫的部分。

                 SWP_NOREPOSITION;與SWP_NOOWNERZORDER標志相同。

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

                 SWP_NOSIZE:維持當前尺寸(忽略cx和Cy參數)。

                 SWP_NOZORDER:維持當前Z序(忽略hWndlnsertAfter參數)。

                 SWP_SHOWWINDOW:顯示窗口。

                 返回值:如果函數成功,返回值為非零;如果函數失敗,返回值為零。若想獲得更多錯誤消息,請調用GetLastError函數。

                 備注:如果設置了SWP_SHOWWINDOW和SWP_HIDEWINDOW標志,則窗口不能被移動和改變大小。如果使用SetWindowLoog改變了窗口的某些數據,則必須調用函數SetWindowPos來作真正的改變。使用下列的組合標志:SWP_NOMOVEISWP_NOSIZEISWP_FRAMECHANGED。

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

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

                 在hWndlnsertAfter參數中沒有設定HWND_NOTOPMOST和HWND_TOPMOST標志。

                 由hWnd參數標識的窗口不是激活窗口。

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

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

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

                 如果應用程序不在前臺,但應該位于前臺,就應調用SetForegroundWindow函數來設置。

                 Windows CE:如果這是一個可見的頂層窗口,并且未指定SWP_NOACTIVATE標志,則這個函數將激活窗口、如果這是當前的激活窗口,并且指定了SWP_NOACTIVATE或SWP_HIDEWINDOW標志,則激活另外一個可見的頂層窗口。

                 當在這個函數中的nFlags參數里指定了SWP_FRAMECHANGED標志時,WindowsCE重畫窗口的整個非客戶區,這可能會改變客戶區的大小。這也是重新計算客戶區的唯一途徑,也是通過調用SetwindowLong函數改變窗口風格后通常使用的方法。

                 SetWindowPos將使WM_WINDOWPOSCHANGED消息向窗口發送,在這個消息中傳遞的標志與傳遞給函數的相同。這個函數不傳遞其他消息。

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

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

            目 錄

            一. 視頻捕獲快速入門

            二.基本的捕獲設置

                      1.設置捕獲速度:

                      2.設置終止捕獲

                      3.捕獲的時間限制

            三.關于捕獲窗口

                      1.創建一個AVICAP捕獲窗口

                      2.將一個捕獲窗口連接至捕獲設備

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

                      4.捕獲窗口的狀態

            四.視頻捕獲驅動和音頻驅動

                      1.視頻捕獲驅動的性能:

                      2.視頻對話框:

                      3.PREVIEW 和 OVERLAY模式:

                      4.視頻格式

                      5.視頻捕獲設置

                      6.聲頻格式

            五.使用視頻捕獲

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

                    2.連接到捕獲驅動(CONNECTING TO A CAPTURE DRIVER)

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

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

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

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

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

                    8. 預覽視頻(PREVIEWING VIDEO)

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

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

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

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

                    13.捕獲數據(CAPTURING DATA)

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

                    15.在程序中加入一個回調函數(ADDING CALLBACK FUNCTIONS TO AN APPLICATION)

                    16.創建一個狀態回調函數(CREATING A STATUS CALLBACK FUNCTION)

                    17.創建一個錯誤回調函數( CREATING AN ERROR CALLBACK FUNCTION)

                    18.創建一個框架回調函數(CREATING A FRAME CALLBACK FUNCTION)

            六.將四個標準對話框改成函數調用形式

                     AUDIOFORMAT對話框

                     VIDEOFORMAT對話框

                     VIDEOSOURCE對話框

                     VIDEO COMPRESSION對話框  

            前 言

                     視頻捕獲是指由專用的視頻采集卡捕獲聲頻和視頻信息,然后將其進行數據化處理,再經過軟件的壓縮進行處理,這時就可對這些數據進行保存、回放、傳輸等各種操作。

                     Windows專門提供了Video for Windows來對視頻處理進行支持,提供的接口可以被大多數的視頻采集卡支持,并有多種視頻壓縮驅動供選擇(當然視頻壓縮可以自己開發),采集卡支持攝像頭,TV等多種輸入。


            一. 視頻捕獲快速入門

                      視頻捕捉將一個視頻流和音頻流數字化, 然后存儲在硬盤或其他存儲介質上.

                      一個AVICap視窗口句柄描述了聲頻與視頻流的細節, 這樣就使你的應用程序從AVI文件格式, 聲頻視頻緩沖管理, 低層聲頻視頻驅動訪問等等解脫出來, AVICap為應用程序提供了一個靈活的介面, 你可以僅僅使用如下幾行代碼就可以將視頻捕捉加入你的程序:

            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);

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

            hWndC = capCreateCaptureWindow ( "My Own Capture Window",

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

            capDriverConnect (hWndC, 0);

            capCaptureSequence (hWndC);


                      當你創建了一個AVICap類的捕捉窗口并將它連接到一個視頻驅動時, 此捕捉窗口即可以開始捕捉數據, 你的程序可以簡單的發送WM_CAP_SEQUENCE消息(或者使用capCaptureSequence宏)來開始捕捉.

                      如果是缺省的設置, WM_CAP_SEQUENCE會開始捕捉視頻音頻流到CAPTURE.AVI文件中, 直到下面的某一事件發生為止:

            用戶按下了ESC鍵或者一個鼠標鍵

            你的應用程序終止或異常中斷捕捉操作

            磁盤已滿


                          在一個應用程序里, 你可以發送WM_CAP_STOP消息來終止捕捉數據(或者使用capCaptureStop宏), 你也可以發送WM_CAP_ABORT消息(或者使用capCaptureAbort宏)來終止.


            二.基本的捕獲設置

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

            例如:

            1.設置捕獲速度:

                       捕捉速度是指捕捉任務每秒鐘捕獲的幀數, 你可以發送WM_CAP_GET_SEQUENCE_SETUP消息(或者使用capCaptureGetSetup宏)來得到當前的捕捉速度, 當前的捕捉速度保存在CAPTUREPARAMS結構的dwRequestMicroSecPerFrame成員變量中, 你可以通過設置此變量來改變當前設置, 單位是每毫秒連續的幀數, 你可以發送WM_CAP_SET_SEQUENCE_SETUP消息(或者使用capCaptureSetSetup宏), dwRequestMicroSecPerFrame的值是66667, 相當于每秒15幀.


            2.設置終止捕獲

                       你可以允許用戶按下某鍵或某組合鍵或者鼠標的左右鍵來終止一個捕獲任務, 如果是實時的捕獲, 則捕獲的文件將會被丟棄; 如果是單步捕獲, 在終止之前所捕獲的內容將會被保存.

                      你可以通過發送WM_CAP_GETQUENCE_SETUP消息(或者使用capCaptureGetSetup宏)來得到當前的設置, 當前的按鍵設置保存在CAPTUREPARAMS的vKeyAbort成員中, 當前的鼠標設置保存在fAbortLeftMouse和fAbortRightMouse成員中. 你可以設置新的按鍵或按鍵組合, 或者鼠標左右鍵, 當你修改的CAPTUREPARAMS后,應該發送WM_CAP_SET_SEQUENCE_SETUP消息來進行更新(或者使用capCaptureSetSetup宏). 缺省的按鍵是VK_ESCAPE. 你必須在指定按鍵之前使用RegisterHotKey函數, 鼠標缺省的值是fAbortLeftMouse和fAbortRightMouse都為TRUE.


            3.捕獲的時間限制

                       CAPTUREPARAMS結構中的fLimitEnabled指示是否有時間限度, wTimeLimit指示最大的持續時間, 單位為秒.

                      得到fLimitEnabled和wTimeLimit的值可以發送WM_CAP_GET_SEQUENCE_SETUP消息(或使用capCatureGetSetup宏), 當設置了這些成員變量后, 應該發送消息WM_CAP_SET_SEQUENCE_SETUP消息(或capCaptureSetSetup宏)來更新CAPTUREPARAMS結構.


            三.關于捕獲窗口

                    在捕獲之前必須創建一個捕獲窗口(capture window),在發送消息或使用宏的過程中都需要使用此窗口。

            1.創建一個AVICap捕獲窗口

                    你可以使用capCreateCaptureWindow函數來創建一個AVICap捕獲窗口, 此函數將會返回一個句柄, 此句柄以后在發送消息時要用.

                    你可以在一個程序里創建一個或多個捕獲窗口, 然后給每一個窗口連接不同的捕獲設置.


            2.將一個捕獲窗口連接至捕獲設備

                       你可以動態的在一個捕獲窗口與一個捕獲設備之前連接或斷接, 你可以發送WM_CAP_DRIVER_CONNECT消息來使一個捕獲窗口與一個捕獲設備連接或關聯. 當連接上以后, 你就可以通過捕獲窗口向捕獲設備發送各種消息.

                    如果你的系統里裝有多個捕獲設備, 你可以在發送WM_CAP_DRIVER_CONNECT消息時用wParam參數指定使用哪一個, 此參數是登記在SYSTEM.INI文件的[drivers]一節里的列表中的某一項, 0為第一個.

                      你可以使用capGetDriverDescription函數來得到已安裝的捕獲設備的名稱及版本, 這樣你的程序就可以列舉所有已安裝的捕獲設備和驅動, 這樣用戶就可以選擇其中的一個來與你的捕獲窗口連接.

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

                     你可以發送WM_CAP_DRIVER_DISCONNECT消息(或capDriverDisconnect宏)來斷接.


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

                       一些象WM_PALETTECHANGED和WM_QUERYNEWPALETTE的系統級消息只能發送到頂級窗口或OVERLAPPED窗口, 如果一個捕獲窗口是子窗口,就必須通過父窗口轉送.

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


            4.捕獲窗口的狀態

                      你可以發送WM_CAP_GET_STATUS消息(或capGetStatus宏)來得到當前捕獲窗口的狀態, 得到的是一個CAPSTATUS結構的拷貝, 它包含圖片的尺寸, 卷軸的當前位置, overlay和preview是否已設置.

                    因為CAPSTATUS信息是動態的, 你的程序應該只要捕獲的視頻流的尺寸或格式可能發生了改變就應該進行刷新(例如: 顯示了捕獲設備的視頻格式以后).

                    改變捕獲窗口的尺寸并不影響實際的捕獲的視頻流的尺寸, 視頻捕獲設備的格式對話框捕獲頻流的尺寸.


            四.視頻捕獲驅動和音頻驅動

            1.視頻捕獲驅動的性能:

                      你可以通過發送WM_CAP_DRIVER_GET_CAPS消息(或者capDriverGetCaps宏)來得到當前連接的視頻驅動的硬件性能. 得到的信息保存在CAPDRIVERCAPS結構中.


            2.視頻對話框:

                      每一個視頻驅動能夠提供四個對話框來控制視頻捕獲和數字化處理, 定義壓縮品質等, 這些對話框都定義在視頻捕獲驅動中.

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

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

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

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


            3.Preview 和 Overlay模式:

                             一個視頻捕獲驅動對進入的視頻流有兩種工作模式: Preview模式和overlay模式, 如果一個捕獲驅動能夠執行兩種方法, 用戶可以在其中選擇一種.

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

            有三種消息控制Preview操作:

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

            WM_CAP_SET_PREVIEWRATE(capPreviewRate宏)當幀在preview模式顯示時設置速度.

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

                      當preview和scaling同時使用, 捕獲的視頻幀將會根據捕獲窗口的尺寸自動縮放, 允許preview模式會自動關閉overlay模式.

                                  overlay模式是一個硬件函數它將數據送入捕獲緩沖區中因而不占用CPU資源. 你可以發送消息WM_CAP_SET_OVERLAY(或capOverlay宏)給捕獲窗口來啟用或終止overlay模式, 允許overlay模式會自動禁止preview模式.

                           你同時也可以在preview模式或overlay模式里發送WM_CAP_SET_SCROLL消息(或capSetScrollPos宏)來設置視頻幀的客戶區卷軸位置.


            4.視頻格式

                        你可以通過發送WM_CAP_GET_VIDEOFORMAT消息(或capGetVideoFormat和capGetVideoFormatSize宏)來得到視頻格式的結構或結構的尺寸. 你可以通過發送CAP_SET_VIDEOFORMAT消息(或capSetVideoFormat宏)來設置視頻格式.


            5.視頻捕獲設置

                       CAPTUREPARMS結構包含了對視頻捕獲流的控制參數, 你可以完成以下這些任務:

            指定幀數

            指定分配多少視頻緩沖

            允許或禁止聲頻捕獲

            指定捕獲的時間間隔

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

            指定終止流的鍵盤或鼠標

            specify the type of video averaging applied during capture.


            得到:WM_CAP_GET_SEQUENCE_SETUP消息(或capCaptureGetSetup宏)

            設置:WM_CAP_SET_SEQUENCE_SETUP消息(或capCaptureSetSetup宏)


            6.聲頻格式

                           你可以通過發送WM_CAP_GET_AUDIOFORMAT消息(或capGetAudioFormat宏和capGetAudioFormatSize宏)來得到當前捕獲音頻數據的格式或尺寸格式。缺省的聲頻格式是:單聲道、8位、11kHz PCM。 當你使用WM_CAP_GET_AUDIOFORMAT時,總是使用WAVEFORMATEX結構。

                         設置發送消息WM_CAP_SET_AUDIOFORMAT消息(或capSetAudioFormat宏),可以傳送WAVEFORMAT,WAVEFORMATEX,PCMWAVEFORMAT結構指針。

            五.使用視頻捕獲

            1.創建捕獲窗口(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.連接到捕獲驅動(Connecting to a Capture Driver)

                       下面的例子是將MSVIDEO驅動連接到句柄為hWndC的捕獲窗口, 然后調用capDriverDisconnect宏來斷接.

            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.列舉所有已安裝的捕獲驅動(Enumerating Installed Capture Drivers)

                       下面的例子使用capGetDriverDescription函數得到已安裝的捕獲驅動的名稱及版本:

            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.得到捕獲驅動的性能(Obtaining the Capabilities of a Capture Driver)

                          發送WM_CAP_DRIVER_GET_CAPS消息可以得到捕獲驅動的性能,并保存入一個CAPDRIVERCAPS結構.每當程序連接一個新的捕獲驅動到一個捕獲窗口時, 就應該更新CAPDRIVERCAPS結構. 下面的程序舉例說明了如何使用capDriverGetCaps宏來得到捕獲驅動的性能:


            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.得到捕獲窗口的狀態(Obtaining the Status of a Capture Window)

                             下面的例子使用SetWindowPos函數使捕獲窗口與進來的視頻流尺寸保持一致, 視頻流的基本信息是使用capGetStatus宏得到的, 保存在CAPSTATUS結構中.


            CAPSTATUS CapStatus;

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

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

            CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);


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

                          每個視頻捕獲卡一般能提供三個不同的對話框用于控制視頻捕獲及數字化處理. 下面的例子說明如何顯示這些對話框, 在顯示這些對話框之前,使用了capDriverGetCaps宏來檢查CAPDRIVERCAPS結構, 以檢測該卡是否有顯示這些對話框:


            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.得到和設置視頻格式(Obtaining and Setting the Video Format)

                               BITMAPINFO結構的長度既適應于標準的也適應于壓縮的數據格式, 所有程序必須總是詢問此結構的尺寸以便在得到當前的視頻格式之前分配內存. 下面的例子就是使用capGetVideoFormatSize宏來得到緩沖區尺寸并調用capGetVideoFormat宏來得到當前的視頻格式.


            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消息)發送一個BITMAPINFO頭結構給捕獲窗口, 因為視頻格式是設備細節, 你的程序應該檢查返回值以便確定此格式是否已被接受.


            8. 預覽視頻(Previewing Video)

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


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

            capPreview(hWndC, TRUE); // starts preview

            // Preview

            capPreview(hWnd, FALSE); // disables preview


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

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


            CAPDRIVERCAPS CapDrvCaps;

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


            if (CapDrvCaps.fHasOverlay)

            capOverlay(hWndC, TRUE);


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

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


            char szCaptureFile[] = "MYCAP.AVI";

            capFileSetCaptureFile( hWndC, szCaptureFile);

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


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

                         下面的例子使用capSetAudioFormat來設置聲頻格式為: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.改變視頻捕獲設置(Changing a Video Capture Setting)

                           下面的例子使用capCaptureGetSetup和capCaptureSetSetup宏得將捕獲幀數從缺省的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.捕獲數據(Capturing Data)

                            下面的例子使用capCaptureSequence宏來開始捕獲視頻并使用capFileSaveAs宏來將捕獲的數據拷貝至NEWFILE.AVI文件中.


            char szNewName[] = "NEWFILE.AVI";

            // Set up the capture operation.

            capCaptureSequence(hWndC);

            // Capture.

            capFileSaveAs(hWndC, szNewName);


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

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


            // 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.在程序中加入一個回調函數(Adding Callback Functions to an Application)

                           一個程序可以為捕獲窗口登記一個回調函數以便在以下的這些情況下通知程序.


            狀態改變

            錯誤發生

            視頻框架和聲頻緩沖區變得可用

            程序應用在捕獲視頻流的過程中接收


                       下面的例子創建一個捕獲窗口并登記狀態,錯誤,視頻流和框架回調函數在消息處理對列中, 也包括了一個終止回調函數的說明.


            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.創建一個狀態回調函數(Creating a Status Callback Function)

                        下面的例子是創建一個簡單的狀態回調函數,登記此回調函數使用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.創建一個錯誤回調函數( Creating an Error Callback Function)

                         下面的例子是創建一個簡單的錯誤回調函數,登記此回調函數使用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.創建一個框架回調函數(Creating a Frame Callback Function)

                          登記此回調函數使用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

            }


             

            六.將四個標準對話框改成函數調用形式

                          系統提供了四個標準的對話框:AudioFormat, VideoFormat, VideoSource, Video Compression,但有時程序希望通過函數控制它們,而不是使用系統提供的那個單一的對話框,此時就應該使用函數調用的方法:


            AudioFormat對話框

                        可以通過使用capSetAudioFormat來實現,此時要使用WAVEFORMATEX結構。

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

            WAVEFORMATEX audioFormat;

            // 確定寬度

            acmMetrics(NULL, ACM_METRIC_MAX_SIZE_FORMAT,&dwSize);

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

            // 設置參數

            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對話框

                              可以通過使用capSetVideoFormat來實現,此時要使用BITMAPINFOHEADER結構。

            例如:設置圖片大小為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對話框

                            沒有找到現成的方法,但視頻捕獲卡提供的CD里面有一個動態鏈接庫可以實現。

            Video Compression對話框

                         可以通過使用ICOpen,ICInfo等函數聯合起來,得到當前系統里面的視頻壓縮驅動的列表,并可選擇其一,MSDN里面有一個程序示范了此用戶,程序名叫:ICWalk。

            posted @ 2009-06-06 18:31 wrh 閱讀(3135) | 評論 (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.  
            //////////////////////////////////////////////////////////////////////////////
            調用capCreateCaptureWindow創建的窗口如何關閉釋放掉?
            小弟不懂VC,只是調的API,用完后但不知道如何關閉掉這個窗口
            網友回復:HWND hWnd = capCreateCaptureWindow(...);

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

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

            下載本文示例代碼

            想要通過ODBC直接讀、寫Excel表格文件,首先,應確保ODBC中已安裝有Excel表格文件的驅動"MICROSOFT EXCEL DRIVER (*.XLS)"。然后,可根據下面步驟進行:

            1. 在StdAfx.h文件中加入

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

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

            1.CString::IsEmpty

            BOOL IsEmpty( ) const;

            返回值:如果CString 對象的長度為0,則返回非零值;否則返回0。

            說明:此成員函數用來測試一個CString 對象是否是空的。

            示例:

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

            // CString::IsEmpty 示例

            CString s;

            ASSERT( s.IsEmpty() );

            請參閱 CString::GetLength

             

            2.CString::Left

            CString Left( int nCount ) const; 

            throw( CMemoryException );

            返回值:返回的字符串是前nCount個字符。

            示例:

            CString s( _T("abcdef") );

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

             

            3.CString::LoadString

            BOOL LoadString( UINT nID );

            throw( CMemoryException );

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

            nID  一個Windows 字符串資源ID。

            說明: 此成員函數用來讀取一個由nID 標識的Windows 字符串資源,并放入一個已有CString 對象中。

            示例:

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

            // CString::LoadString 示例

            #define IDS_FILENOTFOUND 1

            CString s;

            if (! s.LoadString( IDS_FILENOTFOUND ))

             

            4.CString::MakeLower

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

             

            5.CString::MakeReverse

            void MakeReverse( );  //字符倒置

             

            6.CString::MakeUpper

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

             

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

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

             

            8.CString::ReleaseBuffer

            void ReleaseBuffer( int nNewLength = -1 );

            參數:nNewLength

            此字符串的以字符數表示的新長度,不計算結尾的空字符。如果這個字

            符串是以空字符結尾的,則參數的缺省值-1 將把CString 的大小設置為

            字符串的當前長度。

            說明:

            使用ReleaseBuffer 來結束對由GetBuffer 分配的緩沖區的使用。如果你知道緩

            沖區中的字符串是以空字符結尾的,則可以省略nNewLength 參數。如果字符

            串不是以空字符結尾的,則可以使用nNewLength 指定字符串的長度。在調用

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

            示例:

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

            // CString::ReleaseBuffer 示例

            CString s;

            s = "abc";

            LPTSTR p = s.GetBuffer( 1024 );

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

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

            s.ReleaseBuffer(); // 釋放多余的內存,現在p 無效。

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

             

            9.CString::Remove

            int CString::Remove ( TCHAR ch );

            返回值:返回從字符串中移走的字符數。如果字符串沒有改變則返回零。

            參數:ch  要從一個字符串中移走的字符。

            說明:此成員函數用來將ch 實例從字符串中移走。與這個字符的比較是區分大小寫

            的。

            示例:

            // 從一個句子中移走小寫字母'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 );

            返回值:返回被替換的字符數。如果這個字符串沒有改變則返回零。

            參數:chOld     要被chNew 替換的字符。

            chNew    要用來替換chOld 的字符。

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

            LpszNew  一個指向字符串的指針,該字符串包含了要用來替換lpszOld 的字符。

            說明:此成員函數用一個字符替換另一個字符。函數的第一個原形在字符串中用chNew

            現場替換chOld。函數的第二個原形用lpszNew 指定的字符串替換lpszOld 指定

            的子串。

            在替換之后,該字符串有可能增長或縮短;那是因為lpszNew 和lpszOld 的長度

            不需要是相等的。兩種版本形式都進行區分大小寫的匹配。

            示例:

            // 第一個例子,old 和new 具有相同的長度。

            CString strZap( “C - -” );

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

            ASSERT( n == 2 );

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

            // 第二個例子,old 和new 具有不同的長度。

            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” );

            // 注意,現在在你的句子中有了一個額外的空格。

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

             

            11.CString::ReverseFind

            int ReverseFind( TCHAR ch ) const;

            返回值: 返回此CString 對象中與要求的字符匹配的最后一個字符的索引;如果沒有找

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

            參數: ch  要搜索的字符。

            說明:此成員函數在此CString 對象中搜索與一個子串匹配的最后一個字符。此函數

            類似于運行時函數strrchr。

            示例:

            // CString::ReverseFind 示例

            CString s( "abcabc" );

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

             

            12.CString::Right

            CString Right( int nCount ) const; 

            throw( CMemoryException );

            返回值: 返回的字符串是最后nCount個字符。

            CString s( _T("abcdef") );

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

             

            13.CString:: SetAt

            void SetAt( int nIndex, TCHAR ch );

             說明:可以把字符串理解為一個數組,SetAt類似于[].注意nIndex的范圍,如果不合適會有調試錯誤。 Ch 更替字符, 把nIndex位置上的字符 變成ch

             示例:

            CString s( "abc" );

            s.MakeReverse();

            ASSERT( s == "cba" );

             

            14.CString::TrimLeft

            void TrimLeft( );

            void CString::TrimLeft( TCHAR chTarget );

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

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

            str.TrimLeft();

            str為“a”;

             示例2:

            CString str = "abbcadbabcadb ";

            str.TrimLeft("ab");

            結果"cadbabcadb "

            str.TrimLeft("ac");

            結果"bcadbabcadb "

             

            15.CString::TrimRight

            void TrimRight( );

            void CString::TrimRight( TCHAR chTarget );

            void CString::TrimRight( LPCTSTR lpszTargets );

            說明:用法類似于上面。

             

            16.CString::Compare

            int Compare( LPCTSTR lpsz ) const;

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

            示例:

            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,不區分大小字符

             

            18.CString::Collate

            int Collate( LPCTSTR lpsz ) const;

            同CString::Compare

             

            19.CString::CollateNoCase

            int CollateNocase( LPCTSTR lpsz ) const;

            同CString::CompareNoCase

             

            20.CString::CString      //構造函數

            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); 

            返回值:是被刪除前的字符串的長度

            nIndex是第一個被刪除的字符,nCount是一次刪除幾個字符。根據我實驗得出的結果:當nCount>要刪除字符串的最大長度(GetCount() - nIndex)時會出錯,當nCount過大,沒有足夠的字符刪除時,此函數不執行。

            示例:

            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)就會執行錯誤

             

            22.CString::Empty

            Void Empty( );

            返回值:沒有返回值  清空操作;

            示例:

            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 開始; nStar 代表以索引值nStart 的字符開始搜索 ,

            即為包含以索引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 開始

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

            示例:

            CString s( "abcdef" );

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

             

            25.CString::Format

            void Format( LPCTSTR lpszFormat, ... );

            void Format( UINT nFormatID, ... );

            參數:lpszFormat  一個格式控制字符串

            nFormatID  字符串標識符

            示例:

            CString str;

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

            此時Str為13

             

            26.CString::GetAt

            TCHAR GetAt( int nIndex ) const;

            返回值:返回標號為nIndex的字符,你可以把字符串理解為一個數組,GetAt類似于[].注意nIndex的范圍,如果不合適會有調試錯誤。

             

            27.CString::GetBuffer

            LPTSTR GetBuffer( int nMinBufLength );

            返回值:一個指向對象的(以空字符結尾的)字符緩沖區的LPTSTR 指針。

            參數:nMinBufLength

            字符緩沖區的以字符數表示的最小容量。這個值不包括一個結尾的空字符的空間。

            說明:此成員函數返回一個指向CString 對象的內部字符緩沖區的指針。返回的LPTSTR 不是const,因此可以允許直接修改CString 的內容。如果你使用由GetBuffer 返回的指針來改變字符串的內容,你必須在使用其它的CString 成員函數之前調用ReleaseBuffer 函數。

            在調用ReleaseBuffer 之后,由GetBuffer 返回的地址也許就無效了,因為其它的CString 操作可能會導致CString 緩沖區被重新分配。如果你沒有改變此CString 的長度,則緩沖區不會被重新分配。當此CString 對象被銷毀時,其緩沖區內存將被自動釋放。

            注意:如果你自己知道字符串的長度,則你不應該添加結尾的空字符。但是,當你用ReleaseBuffer 來釋放該緩沖區時,你必須指定最后的字符串長度。如果你添加了結尾的空字符,你應該給ReleaseBuffer 的長度參數傳遞-1 ,ReleaseBuffer 將對該緩沖區執行strlen 來確定它的長度。

            示例:

            // CString::GetBuffer 例子

            CString s( "abcd" );

            #ifdef _DEBUG

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

            #endif

            LPTSTR p = s.GetBuffer( 10 );

            strcpy( p, "Hello" ); // 直接訪問CString 對象。

            s.ReleaseBuffer( );

            #ifdef _DEBUG

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

            #endif

             

            28.CString::GetLength

            int GetLength( ) const;

            返回值:返回字符串中的字節計數。

            說明:此成員函數用來獲取這個CString 對象中的字節計數。這個計數不包括結尾的空字符。

            對于多字節字符集(MBCS),GetLength 按每一個8 位字符計數;即,在一個多字節字符中的開始和結尾字節被算作兩個字節。

            示例

            下面的例子說明了如何使用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 );

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

            示例:

            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 閱讀(48207) | 評論 (0)編輯 收藏
            在開發軟件的過程里,經常需要把數據保存到當前執行文件路徑下面,或者讀取當前執行文件路徑下的一些配置信息。這時就需要從當前模塊里獲取所在的目錄路徑,以便進行固定的位置操作文件。要解決這個需求,就需要調用API函數GetModuleFileName來獲取模塊所在的路徑。

            函數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是模塊的句柄,或者設置為NULL表示當前模塊。
            lpFilename是保存路徑的緩沖區。
            nSize是緩沖區的大小。

            調用函數的例子如下:
            #001 //獲取當前程序所在路徑。
            #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        //獲取當前執行文件的路徑。
            #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  }

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

            復制代碼
            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 閱讀(866) | 評論 (0)編輯 收藏

            下載本文示例代碼

            想要通過ODBC直接讀、寫Excel表格文件,首先,應確保ODBC中已安裝有Excel表格文件的驅動"MICROSOFT EXCEL DRIVER (*.XLS)"。然后,可根據下面步驟進行:

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

            #include <odbcinst.h>

            2. 通過ODBC直接創建Excel文件并在表中插入數據(暫定文件名:Demo.xls)
            //創建并寫入Excel文件

            void CRWExcel::WriteToExcel()

            {

              CDatabase database;

              CString sDriver = "MICROSOFT EXCEL DRIVER (*.XLS)"; // Excel安裝驅動

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

              CString sSql;

               

              TRY

              {

                // 創建進行存取的字符串

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

                            sDriver, sExcelFile, sExcelFile);

             

                // 創建數據庫 (既Excel表格文件)

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

                {

                  // 創建表結構(姓名、年齡)

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

                  database.ExecuteSQL(sSql);

             

                  // 插入數值

                  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);

                }     

             

                // 關閉數據庫

                database.Close();

              }

              CATCH_ALL(e)

              {

                TRACE1("Excel驅動沒有安裝: %s",sDriver);

              }

              END_CATCH_ALL;

            }

            3. 通過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驅動 "Microsoft Excel Driver (*.xls)"

                sDriver = GetExcelDriver();

                if (sDriver.IsEmpty())

                {

                    // 沒有發現Excel驅動

                    AfxMessageBox("沒有安裝Excel驅動!");

                    return;

                }

               

                // 創建進行存取的字符串

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

             

                TRY

                {

                    // 打開數據庫(既Excel文件)

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

                   

                    CRecordset recset(&database);

             

                    // 設置讀取的查詢語句.

                    sSql = "SELECT Name, Age "      

                           "FROM demo "                

                           "ORDER BY Name ";

               

                    // 執行查詢語句

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

             

                    // 獲取查詢結果

                    while (!recset.IsEOF())

                    {

                        //讀取Excel內部數值

                        recset.GetFieldValue("Name ", sItem1);

                        recset.GetFieldValue("Age", sItem2);

             

                        // 移到下一行

                        recset.MoveNext();

                    }

             

                    // 關閉數據庫

                    database.Close();

                                        

                }

                CATCH(CDBException, e)

                {

                    // 數據庫操作產生異常時...

                    AfxMessageBox("數據庫錯誤: " + e->m_strError);

                }

                END_CATCH;

            }

            4. 獲取ODBC中Excel驅動的函數
            CString CRWExcel::GetExcelDriver()

            {

                char szBuf[2001];

                WORD cbBufMax = 2000;

                WORD cbBufOut;

                char *pszBuf = szBuf;

                CString sDriver;

             

                // 獲取已安裝驅動的名稱(涵數在odbcinst.h里)

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

                    return "";

               

                // 檢索已安裝的驅動是否有Excel...

                do

                {

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

                    {

                        //發現 !

                        sDriver = CString(pszBuf);

                        break;

                    }

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

                }

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

             

                return sDriver;

            }

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

            本文來自: 乘風原創程序(http://www.qqcf.com) 詳細出處參考:http://study.qqcf.com/web/197/22219.htm

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

            一、 VC 提供的數據庫訪問技術

            ODBC API MFC ODBC DAO OLE DB ADO

            訪問速度:傳統的 ODBC 速度較慢。 OLE DB ADO 都是基于 COM 技術,使用該技術可以直接訪問數據庫的驅動程序,速度大大提高。

             

            可擴展性:通過 OLE DB ActiveX 技術,可以利用 VC 提供的各種組件,控件和第三方提供的組建。從而實現應用程序組件化。

             

            訪問不同數據源:傳統 ODBC 只能訪問關系數據庫。 VC 中提供 OLD DB 技術可以解決該問題。

            二、 幾種技術概述

            1、 ODBC API

            提供一個通用接口,為 ORACLE SQLSERVER 都提供了驅動程序。用戶可以 SQL 語句對數據庫進行直接的底層功能操作。使用時應包含以下頭文件。 ”SQL.H”,”SQLEXT.H”,”SQLTYPES.H”.

            使用步驟如下:

            第一步:分配 ODBC 環境,初始化一些內部結構。完成該步,需要分配一個 SQLHENV 類型的變量在 ODBC 環境中做句柄使用。

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

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

            第四步:進行 SQL 語句操作。操作完就可以斷開與數據庫的連接。

            第五步:釋放 ODBC 環境。

             

            特點:功能強大,提供異步操作,事務處理等高級功能。目前所有關系數據庫都提供了 ODBC 的驅動程序,使用很廣泛。

            缺點:很難訪問對象數據庫和非關系數據庫。

             

            2、 MFC ODBC

             

            為簡化使用 ODBC API VC 提供了 MFC ODBC 類,封裝了 ODBC API

            主要 MFC ODBC 類如下:

            CDatabase 類:一個 CDatabase 對象表示一個到數據源的連接,通過它可以操作數據源。一般不需要直接使用 CDatabase 對象,因為 CDecordSet 對象可以實現大多數功能,但在進行事務處理時, CDatabase 就起到關鍵作用。

            CRecordSet 類:一個 CRecordSet 對象代表一個從數據源選擇的一組記錄的集合 ----- 記錄集。記錄集有兩種形式: snapshot dynaset 。前者表示是靜態視圖。后者表示記錄集與其它用戶對數據庫的更新保持同步。

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

            CDBException 類:由 Cexception 類派生,以 3 個繼承的變量反映對數據庫操作時的異常。

             M_nRetCode: ODBC 返回碼。

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

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

             

            3、 MFC DAO

             

            MFC DAO 是微軟提供的用于訪問 Microsoft Jet 數據庫文件( * Mdb )的工具。當只需訪問 Access 數據庫時用該技術很方便。

            4、 OLE DB

             

            ODBC 技術類似, OLE DB 屬于數據庫訪問技術中的底層接口。

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

            OLEDB 框架定義了應用的 3 個基本類。

             

            數據提供程序 Data Provider 擁有自己的數據并以表格形式顯示數據的應用程序。

            使用者 Consumers :試用 OLEDB 接口對存儲在數據提供程序中對數據進行控制的應用程序。

            服務提供程序 ServiceProvider :是數據提供程序和使用者的組合。

             

            使用 OLE DB 編程時,用戶使用組件對象開發程序,這些組件包括:

            枚舉器:用于列出可用的數據源;

            數據源:代表單獨的數據和服務提供程序,用于創建對話;

            對話:     用于創建事務和命令;

            事務:     用于將多個操作歸并為單一事務處理;

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

            錯誤:     用于獲得錯誤信息。

            5、 ADO

             

            ADO 技術是基于 OLE DB 的訪問接口。繼承了 OLEDB 的優點,并對 OLEDB 的接口作了封裝,定義了 ADO 對象,使開發簡化。 ADO 屬于數據庫訪問的高層接口。

             

            ADO 在服務器應用方面非常有效,特別是動態服務器頁面( ASP )的支持。

             

            ADO 對象結構類似于 OLEDB ,但并不依靠對象層次。大多數情況用戶只需創建并使用需要的對象。下面的對象類組成了 ADO 接口。

             

            Connection  用于表示與數據庫的連接,以及處理一些事務和命令。

            Command    用于處理傳送給數據源的命令。

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

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

            Parameter    在傳送給數據源的命令之間傳遞數據。

            Property      用于操作在 ADO 中使用的其它對象的詳細屬性。

            Errro           用于獲取可能發生的詳細錯誤信息

            posted @ 2009-05-21 21:18 wrh 閱讀(399) | 評論 (0)編輯 收藏
            使用VC編程來操縱Office。你可以實現諸如:Word文件打印、傳送數據到Word文檔、發送E-MAIL、自動產生表格、Excel數據統計、圓餅圖,直方圖顯示、自動報表生成、播放幻燈、doc,txt,HTML,rtf文件轉換、中文簡繁體轉換、拼音或筆畫排序......只要是Office能夠實現的功能,都可以在你寫的程序中調用。仔細閱讀下面的說明,并下載源文件進行參考,你就可以一步一步地掌握這個技術。祝朋友們學習快樂。

              一、概念

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

              二、結構層次

              為了更有邏輯,更有層次地操作 Office,Microsoft 把應用(Application)按邏輯功能劃分為如下的樹形結構

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

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

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

              (1)創建(或打開已有的)一個 MFC 的程序工程

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

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

            Office 版本和類型 類型庫文件 Office 版本和類型 類型庫文件
            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)選擇類型庫文件后,在彈出的對話窗中繼續選擇要添加的類。具體選擇什么類,要看你將來在程序中打算調用什么功能。當然,你也可以不用考慮這么多,用鼠標和Shift鍵配合,全部選擇也可以。

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

              (6)在你需要調用 Office 功能函數的 cpp 文件中

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

              (7)好了,現在開始寫程序吧。另外要說明的是,步驟3和4,其實也可以使用 #import 方式引入類型庫。

              四、實現技巧

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

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

              以上是在 Word 中錄制的一個保存文件的宏,而在 VC 中對應的函數原型為 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)

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

              五、步步為營

              特別提示一:編譯執行前,一定要先關閉 KV 實時監視病毒的功能(KV 的程序會干擾我們的調用,瑞星的則沒關系)。

               特別提示二:在例子程序中,為了表現程序的關鍵部分,沒有或很少使用了條件判斷。為了實現你程序的健壯性,請自己加上條件判斷和異常處理。

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

              以上這6個小程序中,都有詳細的注釋。大家閱讀后慢慢體會并實驗,你就可以自由地操縱任何一個 Office 啦。

              源代碼下載

            posted @ 2009-05-21 21:14 wrh 閱讀(323) | 評論 (0)編輯 收藏
            僅列出標題
            共25頁: First 12 13 14 15 16 17 18 19 20 Last 

            導航

            <2008年4月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            統計

            常用鏈接

            留言簿(19)

            隨筆檔案

            文章檔案

            收藏夾

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            国内精品久久久久影院薰衣草| 狠狠色丁香久久婷婷综合图片| 久久久久人妻精品一区| 亚洲国产成人乱码精品女人久久久不卡| 日本精品一区二区久久久| 久久久婷婷五月亚洲97号色| 国产一区二区精品久久岳| 久久亚洲国产精品成人AV秋霞| 日韩精品久久无码人妻中文字幕| 久久国产免费观看精品| 欧美日韩久久中文字幕| 久久综合九色综合欧美狠狠| 久久久久青草线蕉综合超碰| 国产精品久久久久乳精品爆| A级毛片无码久久精品免费| 久久91这里精品国产2020| 99久久99久久久精品齐齐| 久久综合鬼色88久久精品综合自在自线噜噜 | 国产精品九九久久免费视频| 热re99久久精品国99热| 色老头网站久久网| 久久精品这里只有精99品| 久久精品www人人爽人人| 久久精品人妻中文系列| 久久久这里有精品中文字幕| 老司机国内精品久久久久| 狠狠色婷婷久久一区二区三区| 亚洲精品乱码久久久久久蜜桃图片| 欧美午夜A∨大片久久 | 久久亚洲AV成人无码国产| 亚洲国产天堂久久综合| 久久久久18| 亚洲午夜久久久| 精品久久久久成人码免费动漫| 欧美久久一区二区三区| 亚洲欧洲精品成人久久曰影片 | 国产亚洲精品自在久久| 99久久国产综合精品麻豆| 精品久久久久久中文字幕人妻最新| 久久精品aⅴ无码中文字字幕重口| 久久亚洲私人国产精品vA|