當前位置:首頁 » 編程軟體 » vc控制項編程

vc控制項編程

發布時間: 2023-05-15 14:25:40

⑴ 如何用VC進行串口編程

1、新建MFC對話框工程如下

雙擊兩個Button按鈕;

代碼中顯示如下:

[cpp] view plain print?

  • voidCMSCommTestDlg::OnBnClickedBtnopen()

  • {

  • //TODO:

  • }

  • voidCMSCommTestDlg::OnBnClickedBtnsend()

  • {

  • //TODO:

  • }

  • voidCMSCommTestDlg::OnOncommMscomm1()

  • {

  • //TODO:Addyourmessagehandlercodehere

  • }

  • void CMSCommTestDlg::OnBnClickedBtnopen()

  • {

  • // TODO: Add your control notification handler code here

  • }

  • void CMSCommTestDlg::OnBnClickedBtnsend()

  • {

  • // TODO: Add your control notification handler code here

  • }

  • void CMSCommTestDlg::OnOncommMscomm1()

  • {

  • // TODO: Add your message handler code here

  • }


  • 5、將上面代碼補全如下:

    [cpp] view plain print?

  • voidCMSCommTestDlg::OnClickedBtnopen()

  • {

  • //TODO:

  • //如果埠已經開啟,那麼先關閉

  • if(m_comm1.get_PortOpen())

  • {

  • m_comm1.put_PortOpen(FALSE);

  • }

  • m_comm1.put_CommPort(3);//選擇com3,可以根據具體情況更改

  • m_comm1.put_InBufferSize(1024);//設置輸入緩沖區的大小,Bytes

  • m_comm1.put_OutBufferSize(1024);//設置輸出緩沖區的大小,Bytes

  • m_comm1.put_Settings(_T("9600,n,8,1"));//波特率9600,無校驗,8個數據位,停止位1

  • m_comm1.put_InputMode(1);//1:表示以二進制方式檢索數據

  • m_comm1.put_RThreshold(1);//參數1表示每當串口接收緩沖區中有多於或等於1個字元時將引發一個接收數據的OnComm事件

  • m_comm1.put_InputLen(0);//設置當前接收區長度是0

  • if(!m_comm1.get_PortOpen())

  • {

  • m_comm1.put_PortOpen(TRUE);

  • }

  • else

  • {

  • AfxMessageBox(_T("Cannotopenserialport!"));

  • }

  • m_comm1.get_Input();//先預讀緩沖區以清除殘留數據

  • UpdateData(FALSE);

  • }

  • voidCMSCommTestDlg::OnClickedBtnsend()

  • {

  • //TODO:

  • UpdateData(TRUE);

  • m_comm1.put_Output(COleVariant(m_sTXDATA));//發送數據

  • }

  • voidCMSCommTestDlg::OnOncommMscomm1()

  • {

  • //TODO:Addyourmessagehandlercodehere

  • VARIANTvariant_inp;

  • COleSafeArraysafearray_inp;

  • LONGlen,k;

  • BYTErxdata[2048];

  • CStringstrtemp;

  • if(m_comm1.get_CommEvent()==2)//事件值為2表示緩沖區內有字元

  • {

  • variant_inp=m_comm1.get_Input();//讀緩沖區

  • safearray_inp=variant_inp;//VARIANT型變數轉換為ColeSafeArray型變數

  • len=safearray_inp.GetDim();//得到有效數據長度

  • for(k=0;k<len;k++)

  • {

  • safearray_inp.GetElement(&k,rxdata+k);//轉換為BYTE型數組

  • }

  • for(k=0;k<len;k++)//將數組轉換為CString型變數

  • {

  • BYTEbt=*(char*)(rxdata+k);//字元型

  • strtemp.Format(_T("%c"),bt);//將字元送入臨時變數strtemp存放

  • m_sRXDATA+=strtemp;//接收到的數據放到編輯框對應的變數中

  • }

  • }

  • SetDlgItemText(IDC_EDIT_RXDATA,m_sRXDATA);

  • }

⑵ VC++編寫ActiveX控制項


ActiveX這門技術棚正是通過生成「*.ocx」文件來實現的。先來了解下OCX文件,在網路上面對OCX是這樣解釋的:「.ocx是ocx控制項的擴展名,OCX 是對象類別擴充組件。如果你用過Visual Basic或者Delphi一類的可視化編程工具,那麼對控制項這個概念一定不會陌生,就是那些工具條上的小按鈕,如 EditBox,Grid,ImageBox,明帆Timer等等。每個控制項都有自己的事件、方法和屬性。使用了控制項的編程非常容易。首先,在程序的設計階段可以設置一些屬性,如大小,位置,標題(caption)等等;在程序運行階段,可以更改這些屬性,還可以針對不同的事激和雹件,調用不同的方法來實現對該控制項的控制。控制項就好像一塊塊的積木,程序要做的事只是將這些積木搭起來。控制項的最大好處是可以重復使用,甚至可以在不同的編程語言之間使用,例如你可以在 VB中嵌入用VC開發的控制項。」
裡面最後一句話比較重要,就是用VC開發的OCX控制項,你可以在其它語言裡面都能調用,這樣很好的實現了功能化組件的良好循環使用,而且還可以實現跨語言地調用(例如,你完全可以用C#調用C++開發的OCX控制項)。
下面開始介紹,如何用VC++一步步生成你想要的「*.ocx」文件。
1. 建立最簡單的ocx文件並進行調試
1.1 建立最簡單的ocx文件
VC-新建項目-MFC ActiveX WinZard
一路點擊「確定」,直到點擊「完成」。最後VC++會自動生成一些文件,這些文件就構成了ActiveX的基本模板,文件的主要結構如下:
直接編譯一下,然後在Debug目錄下面就會生成一個名為「ocxDemo.ocx」的控制項注冊文件,然後利用「regsvr32」命令就可以實現本機對此控制項的注冊,然後就可以使用本語言或者跨語言編寫程序時引用此控制項來實現相應的功能(後面將會講到)。
1.2 ocx調試方法:
VC++自帶有一個調試控制項的工具「ActiveX控制項測試容器」,通過三種方式可以打開:
1.點擊「調試」按鈕,會出現如下對話框:
然後瀏覽"C:Program FilesMicrosoft Visual StudioCommonToolsTSTCON32.EXE「
2. 系統的「開始「-》「程序」-》「Microsoft Visual C++ 6.0」-》「Microsoft Visual C++ 6.0 Tools」-》「Active Control Test Container」
3. VC++開發環境中的「工具」-》「ActiveX Control Test Container」
通過上面的任意一種方法,都可以調出下面的程序:
右擊空白區域,插入控制項,然後會彈出下面的對話框:
選中指定控制項,然後點擊確定,控制項就被載入到此工具中了,然後可以通過這個工具來看此控制項的相關事件響應等等。
2.自VC++生成的模板基礎上自定義功能
所有的自定義功能基本上都來自於「MFC ClassWizard」類向導對話框。
(「快捷鍵Ctrl+W」或者「查看」-「建立類向導」)
在「Automation」選項卡中為控制項添加方法和屬性。
在「ActiveX Events」選項卡中為控制項添加事件。
2.1 添加控制項屬性
切換到「Automation」選項卡中,點擊右邊的「Add Property」會彈出對話框:
External name:外部名稱。指此控制項被使用時,外部程序看到的屬性名稱,僅在外部引用時被使用。
Type:屬性類型。除了基本的整形等數據類型外,還有很多復雜的高級數據類型。
Variable name:變數名稱。此屬性在控制項源文件中的變數名稱,在編寫控制項源碼時使用。
Notification function:提醒函數。當此屬性被改變時,會觸發此提醒函數。
Implementation:實現方式。指屬性的三種類型:固有型,成員變數型,Get/Set方法型。固有型是指系統賦予的固有屬性,如背景色,標題;成員變數型是用戶自定義的屬性;Get/Set方法型,可能是指只能通過Get/Set方法才能獲取和改變的變數吧(這個沒研究)。
2.2 添加控制項方法
在「Automation」選項卡中,點擊右邊的「Add Method」會彈出對話框:
External name:方法外部名稱。
Internal name:方法內部名稱。
Return type:返回值類型。除了基本的整形等數據類型外,還有很多復雜的高級數據類型。
Implementation:實現方式。兩種:固有方法,自定義方法。
Parameter list:參數列表。參數名稱和參數類型:參數類型包含很多高級數據類型。
2.3 添加控制項事件
切換到「ActiveX Events」選項卡中,點擊右邊的「Add Event」會彈出對話框:
External name:事件外部名稱。
Internal name:事件內部名稱。比外部名稱多了個前綴「Fire」。
Implementation:實現方式。兩種:固有事件,自定義事件。固有事件一般是滑鼠移動,雙擊等等事件,這些事件都由系統消息觸發;自定義事件則是完全由用戶定義的一個函數,但這個函數需要用戶在源文件中調用(在內部調用,對於控制項的使用方來說,就相當於在調用的地方此事件被觸發,而內部傳入的參數,則是此事件產生的消息附帶信息)。
Parameter list:參數列表。參數名稱和參數類型:參數類型包含很多高級數據類型。
總述:通過「類向導」工具,為控制項添加屬性、方法和事件後,VC++會自動在相應的文件裡面生成代碼,比如內部方法屬性和外部方法屬性之間的映射,消息的建立,消息的聲明,等等。如果用戶要對引進行深入研究,還需要對程序的結構比較熟悉,知道各部分代碼的作用,知道哪些地方的代碼是系統自動生成的,哪些代碼需要用戶手動加入的。Visual C++開發環境雖然有很多優點,但有個缺點也很明顯,就是代碼結構比較亂,感覺沒有VS2005和後面的Visual Studio系列要好。但是由於VC6.0作為一個比較經典的開發環境,而且網上的有關C++的程序設計基本上都是基於VC6.0的,所以,有必要對其進行學習,便於自己讀懂網上的代碼並進行消化吸收。
2.4 生成ocx文件並調試
直接編譯用戶加入了自定義代碼的項目,然後在項目的Debug目錄下面會生成一個ocx文件,這個就是此控制項的注冊文件了。
控制項的調試工具仍然是「ActiveX Control Test Container」。
假設我們在控制項中加入了一個事件:固有事件——「MouseMove」滑鼠移動事件;用戶自定義事件——ocxClick事件(此事件是通過「WM_MOUSEMOVE」消息來觸發的,返回的是滑鼠當前位置的x坐標)。
運行「ActiveX Control Test Container」並插入當前控制項,當滑鼠在上面移動的時候,可以看到MouseMove產生了事件了。
同時可以通過「Control」-》「Invoke Method」來對控制項的方法進行測試,測試的方法就是你輸入參數,它返回計算結果(下面以自定義的方法funHello為例)。
3.控制項的使用方法
3.1 注冊控制項
ocx控制項的安裝方式有很多種,這里介紹最簡單的一種。
步驟:
1.將需要安裝的OCX控制項文件復制到某個目錄,例如C盤根目錄下。
2.進入開始,點擊運行。
3.在出現的框中鍵入regsvr32 C:/xxxx.ocx 。(XXXX為控制項名, C:/為目錄)
4.點擊確認後等待出現提醒注冊成功即可。
3.2 ActiveX控制項的調用
ActiveX作為一種通用的COM組件,可以被不同語言調用的。
3.2.1 通過VC++調用
利用VC6.0建立一個MFC的基本對話框應用程序
在完成程序向導後。執行下面的步驟:
1. 執行「工程」-》「添加到工程」--》「Components and Controls」。
2. 在彈出的文件瀏覽對話框中,找到Registered ActiveX Controls文件目錄下的你剛才注冊的控制項,比如「OcxDemo Control」,然後點擊「Insert」按鈕即可將此控制項添加到控制項工具條集合中。
3. 將控制項工具條上新增加的OCX控制項拖入到應用程序主窗口中。
完成上面的步驟後,就可以像使用普通控制項一樣在VC中使用此控制項了(右擊此控制項,可以查看此控制項的「事件」和「屬性」,就是你在編寫控制項源碼時的那些「外部名稱External name」)。
3.2.2 通過C#調用
其實這個才是重點,因為跨語言調用ActiveX技術最被筆者看好的地方。
用Visual Studio 2005新建一個C#.NET的Windows窗口程序,然後在工具箱面板上,右擊「選擇項」,選擇COM組件,找到你注冊的ActiveX控制項:
確定後,那個OcxDemo Control控制項就載入到工具箱裡面了。可以直接拖動這個控制項到C#.NET應用程序的主窗口上去了,然後就像使用普通控制項那樣使用此控制項了。
比如,本文中的ActiveX控制項的自定義事件中,是通過滑鼠移動來觸發,那麼在應用程序中,只要滑鼠移動到控制項上,那麼就會觸發此自定義事件,並獲取當前滑鼠位置的橫坐標。
4. 最後一些Tip
1) 在自定義控制項時,可在控制項源碼的OnDraw()函數中設置控制項的外觀(也就是控制項被拖入到應用程序中時呈現的樣子,一般默認是一個白色的方框內切橢圓的樣式)。
2) 用C#來使用ActiveX的事件時,事件所產生的數據都包含在Event變數中,只需要用個點運算符就可以取出來了。
5.展望
控制項函數的返回值類型那麼多,那麼復雜,如果要用得好,還需要對那些OLE數據類型進行好好學習,這個等今後需要時再慢慢學習吧。

⑶ 如何用vc編寫程序

第一篇

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

初始化對象模型

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

與記事本相結合,需要奪取主窗體的句柄和覆蓋了整個客戶端區域的編輯控制項的句柄。可以用C++ FindWindow API函數檢索第一個打開的並且和記事本的Windows類名「notepad」相匹配的窗口(此後台信息已經可以由Spy++提供,它是一個Visual Studio工具,可以透視Windows的隱私),可以使用以下的C++代碼:

STDMETHODIMP

CNotepadApplication::Load(BSTR bstrFile)

{

m_hwnd = FindWindow(_T("notepad"), NULL);

if (!IsWindow(m_hwnd))

_StartApp(OLE2T(bstrFile));

Load方法嘗試找到一個運行中的記事本實例。如果成功,它忽略輸入的文件名。否則,它產生nodepad.exe,並用命令行傳遞bstrFile參數。

這是僅有的可能的方法來做到這些了。可以更改Load方法的行為遵守其他的規則。然而,需要注意的是,在程序的用戶介面中隱蔽地載入一個文本文件是通過命令行來實現的。否則,必須求助File菜單中的Open命令,但這就不是自動和隱蔽的了。

一旦找到了記事本主窗體的句柄,就可以利用它並使用C++代碼檢索子編輯控制項。

m_hwndEdit = FindWindowEx(

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

記事本的結構提供了一個類名為「notepad」的窗口,它的客戶區域被一個編輯控制項占據——一個類名為「edit」的窗口。FindWindowsEx API函數檢索第一個類名為「edit」的窗口,它是m_hwnd的子女。

下一步,在COM對象中創建一個屬性,它描述子編輯控制項的內容。調用名為Text的可讀寫屬性。給它一個文本內容,它將會立即影響到記事本的緩沖區。

Set npad = CreateObject("NotepadOM.Application")

npad.Load ""

npad.Text = "Sample text"

在前面的代碼中,我們建立了一個新的未明名的文本文檔,它的內容已經被賦予了某個字元串。當然,可以使用Text屬性連接文本到其他變數中。

npad.Text = "Sample text"

npad.Text = npad.Text & vbCrLf & "for the article"

即使記事本是個SDI程序,也可能需要像清晰的對象調用過程那樣公開文本內容,例如文檔操作。這符合更清楚、更雅緻的模型設計,但是它仍需要為架構設計帶來多餘的復雜性。為什麼創建一個新的ATL對象僅僅是為了優化一些文本相關的功能呢?

在實現Text屬性時,利用了Windows32編輯控制項的一個鮮為人知的特性。所有Windows32控制項不能跨進程訪問。例如,不能請求另一個應用程序的rich edit box以字元串類型返回它的內容。產生這個問題的原因是,任何內存地址只在進程管理范圍內才有效。這個規則有少部分例外。

所有的Windows標准控制項buttons、listboxes、和edit controls或者其他控制項都不違背這項規則。它們的內容以在進程間被任意地讀或寫。這功能在Windows 95時為了保持向後兼容現存的Windows3x程序就出現了,它用進程間子類化。此同樣存在於Windows XP和Windows 2000中。

可以使用一些消息,如WM_GETTEXT和WM_SETTEXT來獲得或寫入文本框的內容而不顧實際進程的相關情況。同樣,當運行VBS腳本時,實際上已涉及到兩個不同的進程,記事本和wscript.exe,它們控制著VBS腳本。用C++實現此Text屬性,代碼如下:

STDMETHODIMP

CNotepadApplication::get_Text(BSTR *pVal)

{

USES_CONVERSION;

int nLen = 1 + SendMessage(m_hwndEdit, WM_GETTEXTLENGTH, 0, 0);

LPTSTR pszBuf = new TCHAR[nLen];

SendMessage(m_hwndEdit, WM_GETTEXT, nLen, (LPARAM) pszBuf);

*pVal = SysAllocString(T2OLE(pszBuf));

delete [] pszBuf;

return S_OK;

}

STDMETHODIMP

CNotepadApplication::put_Text(BSTR newVal)

{

USES_CONVERSION;

SendMessage(m_hwndEdit, WM_SETTEXT, 0, (LPARAM) OLE2T(newVal));

return S_OK;

}

添加編輯函數

訪問編輯控制項的句柄可以弄清編輯所需的一串函數——特別是關於文本選擇的部分。可以很容易地添加方法選擇所有的緩沖區中的文本或限制為某個區域選擇。SelectAll和SelectText用C++實現,方法如下:

STDMETHODIMP

CNotepadApplication::SelectText(

int nFrom, int nTo) {

SendMessage(m_hwndEdit, EM_SETSEL, nFrom-1, nTo-1);

return S_OK;

}

通過EM_SETSET消息可以很容易地在編輯控制項中實現文本選擇。在Windows32中,第一個可選的字元是在0位置,但是相關方法使它從1開始。而指定-1~0的范圍可以選擇整個文本。

編輯框中正文的字體名稱由某個注冊值lfFaceName決定,在以下位置可以找到此鍵值:

HKEY_CURRENT_USER

\Software

\Microsoft

\Notepad

將它設為想要用的鍵值。記事本在啟動之前讀取這個設置。為了使它生效,請記住在調用Load之前設置好它。

set npad = CreateObject("NotepadOM.Application")

npad.Font = "Lucida Console"

npad.Load "readme.txt"

當一個互動式的用戶單擊菜單時,例如「File | Open」,主窗體發送WM_COMMAND消息,其中WPARAM參數被賦予串聯的兩個字。低位字是命令的ID,高位字包含消息碼或表示觸發的值——鍵盤加速鍵或菜單。用C++調用一個菜單命令、發送一個WM_COMMAND消息到記事本,代碼如下:

SendMessage(m_hwnd, WM_COMMAND,

MAKELONG(nCommand,0), 0);

必須用特殊的工具為nCommand參數指出正確的值,就像Spy++。既然這樣,我稍微修改文章中所描述的DLL版本。「Hook,Line and Sinker」〔Visual C++ Developers Journal February 2001〕。此常式產生並鉤住,然後創建記事本的子類。它過濾窗口接收到的所有消息,並在命令代碼是WM_COMMAND時彈出對話框顯示command ID。

if (uiMsg == WM_COMMAND) {

// Get the value of LOWORD(wParam)

}

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

const NOTEPAD_FILE_OPEN = 10

Set npad = CreateObject("NotepadOM.Application")

npad.InvokeMenu NOTEPAD_FILE_OPEN

如果要編程關閉運行中的實例,需要想到在記事本窗口上調用DestroyWindows。然而,DestroyWindows只能在屬於同一進程的窗口的進程中調用。要卸載記事本,用C++簡單的發送一條退出代碼的WM_COMMAND消息:

SendMessage(m_hwnd, WM_COMMAND,

MAKELONG(28,0), 0);

有些功能是無法從非自動化的程序中獲得的。例如,打開文件和另存為是不可能實現的,因為程序並不通過消息或API暴露這些代碼,需要編寫代碼來存儲它。舉個例子來說,在記事本中,存儲運行時結果需要響應Save或Save As命令,但是它們都是互動式的命令,需要用戶單擊OK按鈕或輸入一個新的文件名。這是原解決方案固有的限制。

最近,在一個客戶中碰到一個相似的問題,我應要求在不同環境處理一些傳統的Windows程序(其中一個是記事本)。本質上來說,Win32 made-to-measure應用程序獲得TCP/IP通道指令並轉換它們以執行本地的Windows應用程序。通過Windows32消息請求服務的方式和在此所做的很相似。下一目標是用COM對象模型封裝此通信模式。

關於作者

Dino Esposito是Wintellect的ADO.NET專家和培訓師並且在羅馬當咨詢師。Dino是《Building Web Solutions With ASP.NET and ADO.NET》(微軟出版)一書的作者,是VB-2-The-Max (http://www.vb2themax.com <http://www.vb2themax.com>)的創始人。可通過[email protected]聯繫到Dino。

熱點內容
壓縮機工作原理圖 發布:2025-07-13 18:10:15 瀏覽:38
黑暗追求者安卓怎麼聯機 發布:2025-07-13 18:10:07 瀏覽:617
北大保安自學編程 發布:2025-07-13 18:09:58 瀏覽:858
java遞歸排列 發布:2025-07-13 18:02:43 瀏覽:473
輕量雲伺服器如何換成d盤 發布:2025-07-13 17:58:45 瀏覽:931
重置騰訊雲伺服器時間 發布:2025-07-13 17:54:55 瀏覽:326
aes256java加密 發布:2025-07-13 17:54:46 瀏覽:709
mc開伺服器的電腦 發布:2025-07-13 17:46:47 瀏覽:195
事件linux 發布:2025-07-13 17:45:51 瀏覽:143
mssqlpython 發布:2025-07-13 17:24:34 瀏覽:469