當前位置:成語大全網 - 漢語詞典 - 如何用vc寫程序

如何用vc寫程序

第壹篇文章

為非COM程序添加對象模型(2)

初始化對象模型

創建壹個新的組件實例,並調用Load方法來獲得壹對結果。首先,連接到記事本的運行副本。其次,在記事本窗口中打開壹個現有文檔或創建壹個空文檔。

結合記事本,需要抓住主窗體的句柄和覆蓋整個客戶區的編輯控件的句柄。可以使用C++ FindWindow API函數檢索第壹個打開的窗口,該窗口與記事本的Windows類名“notepad”相匹配(這個後臺信息已經可以由Spy++提供,Spy ++是壹個可以看穿Windows隱私的Visual Studio工具),可以使用下面的C++代碼:

STDMETHODIMP

加載(BSTR bstrFile)

{

m_hwnd = FindWindow(_T(“記事本”),NULL);

如果(!IsWindow(m_hwnd))

_ StartApp(OLE2T(bstrFile));

Load方法試圖找到壹個正在運行的記事本實例。如果成功,它將忽略輸入的文件名。否則,它會生成壹個nodepad.exe,並在命令行上傳遞bstrFile參數。

這是唯壹可行的方法。您可以更改Load方法的行為並遵循其他規則。但是需要註意的是,在程序的用戶界面加載文本文件是通過命令行實現的。否則,您必須轉到文件菜單中的打開命令,但這不是自動的和隱藏的。

壹旦找到記事本主窗體的句柄,就可以使用它並使用C++代碼來檢索子編輯控件。

m _ hwndEdit = FindWindowEx(

m_hwnd,NULL,_T("edit "),NULL);

記事本的結構提供了壹個名為“記事本”的窗口,它的客戶區被壹個編輯控件占用——壹個名為“編輯”的窗口。FindWindowsEx API函數檢索第壹個名為“edit”的窗口,它是m_hwnd的子窗口。

接下來,在COM對象中創建壹個描述子編輯控件內容的屬性。調用壹個名為Text的讀寫屬性。給它壹個文本內容,馬上就會影響記事本的緩沖。

set npad = CreateObject(" NotepadOM。應用”)

npad。載入""

npad。Text = "示例文本"

在前面的代碼中,我們創建了壹個新的未命名的文本文檔,其內容被賦予了壹個字符串。當然,您可以使用Text屬性將文本連接到其他變量。

npad。Text = "示例文本"

npad。Text = npad。文本& ampvbCrLf & amp;“為文章”

即使記事本是壹個SDI程序,妳也可能需要暴露文本內容,比如文檔操作,像壹個明確的對象調用過程。這符合更清晰、更優雅的模型設計,但還是要給架構設計帶來不必要的復雜性。為什麽創建壹個新的ATL對象只是為了優化壹些文本相關的函數?

當實現文本屬性時,使用了Windows S32編輯控件的壹個鮮為人知的特性。所有的Windows32控件都不能跨進程訪問。例如,您不能請求另壹個應用程序的富編輯框以字符串類型返回其內容。出現這個問題的原因是任何內存地址都只在進程管理的範圍內有效。這條規則有幾個例外。

所有Windows標準控件按鈕、列表框和編輯控件或其他控件都不違反此規則。它們的內容可以在進程間任意讀取或寫入。為了保持Windows 95中的向後兼容性,這個函數出現在現有的Windows3x程序中,它在進程之間被子類化。這也存在於Windows XP和Windows 2000中。

您可以使用壹些消息,如WM_GETTEXT和WM_SETTEXT,來獲取或寫入文本框的內容,而不管實際的過程。類似地,當運行VBS腳本時,實際上涉及兩個不同的進程,記事本和wscript.exe,它們控制VBS腳本。用C++實現這個文本屬性,代碼如下:

STDMETHODIMP

CNotepadApplication::get _ Text(BSTR * pVal)

{

USES _ CONVERSION

int nLen = 1+SendMessage(m _ hwndEdit,WM_GETTEXTLENGTH,0,0);

新TCHAR[nLen];

SendMessage(m_hwndEdit,WM_GETTEXT,nLen,(LPARAM)PSZ buf);

* pVal = SysAllocString(T2OLE(PSZ buf));

刪除[]PSZ buf;

返回S _ OK

}

STDMETHODIMP

CNotepadApplication::put _ Text(BSTR·紐瓦爾)

{

USES _ CONVERSION

SendMessage(m_hwndEdit,WM_SETTEXT,0,(LPARAM)OLE2T(new val));

返回S _ OK

}

添加編輯功能

訪問編輯控件的句柄可以明確編輯所需的壹系列功能——尤其是關於文本選擇的部分。您可以輕松地添加方法來選擇緩沖區中的所有文本,或者將選擇限制在某個區域。SelectAll和SelectText在C++中實現如下:

STDMETHODIMP

cno tepad application::select text(

int nFrom,int nTo) {

SendMessage(m _ hwn edit,EM_SETSEL,nFrom-1,nTo-1);

返回S _ OK

}

通過EM_SETSET消息,可以在編輯控件中輕松實現文本選擇。在Windows32中,第壹個可選字符在位置0,但相關方法使其從1開始。指定範圍-1 ~ 0可以選擇整個文本。

編輯框中文本的字體名稱由註冊值lfFaceName決定,該值可在以下位置找到:

HKEY _當前_用戶

\軟件

\微軟

\記事本

將其設置為所需的鍵值。記事本在啟動前讀取該設置。為了使它生效,請記住在調用Load之前設置它。

set npad = CreateObject(" NotepadOM。應用”)

npad。Font = "Lucida控制臺"

npad。加載“readme.txt”

當交互式用戶單擊壹個菜單時,比如“File | Open ”,主表單會發送壹條WM_COMMAND消息,其中WPARAM參數由兩個單詞組成。低位字是命令的ID,高位字包含消息代碼或指示觸發鍵盤快捷鍵或菜單的值。用C++調用菜單命令,發送WM_COMMAND消息到記事本。代碼如下:

SendMessage(m_hwnd,WM_COMMAND,

MAKELONG(nCommand,0),0);

您必須使用特殊的工具來指出nCommand參數的正確值,就像Spy++壹樣。在這種情況下,我稍微修改了文章中描述的DLL版本。《鉤、線、墜》﹔Visual c++開發人員雜誌2006年2月5438+0】這個例程生成並掛鉤,然後創建Notepad的壹個子類。它過濾窗口收到的所有消息,當命令代碼為WM_COMMAND時,會彈出壹個對話框顯示命令ID。

if (uiMsg == WM_COMMAND) {

//獲取LOWORD(wParam)的值

}

妳需要添加的只是壹個存儲或顯示命令代碼的程序。驗證主記事本的菜單命令ID。只要給出了這些,調用菜單命令就非常簡單,代碼如下:

const NOTEPAD _ FILE _ OPEN = 10

set npad = CreateObject(" NotepadOM。應用”)

npad。InvokeMenu記事本_文件_打開

如果希望以編程方式關閉正在運行的實例,需要在記事本窗口中調用DestroyWindows。但是,DestroyWindows只能在屬於同壹進程的窗口的進程中調用。要卸載記事本,只需發送壹條WM_COMMAND消息,用C++退出代碼:

SendMessage(m_hwnd,WM_COMMAND,

MAKELONG(28,0),0);

壹些功能不能從非自動化程序中獲得。比如,打開壹個文件,保存為,是不可能的,因為程序不會通過messages或者API公開代碼,需要寫代碼來存儲。例如,在記事本中,存儲運行時結果需要響應Save或Save As命令,但它們是交互式命令,需要用戶單擊確定按鈕或輸入新的文件名。這是原始解決方案的固有限制。

最近在壹個客戶身上遇到了類似的問題,應該是要求我在不同的環境下處理壹些傳統的Windows程序(其中壹個是記事本)。本質上,Win32定制應用程序獲取TCP/IP通道指令,並將其轉換為執行本地Windows應用程序。通過Windows S32消息請求服務的方式與這裏所做的非常相似。下壹個目標是用COM對象模型封裝這種通信模式。

關於作者

Dino Esposito是ADO.NET Wintellect的專家和培訓師,也是羅馬的顧問。迪諾是《與ASP.NET和ADO.NET壹起構建Web解決方案》(由微軟出版)的作者,也是VB-2-The-Max(