全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:9095
推到 Plurk!
推到 Facebook!

從基本面開始吧!

 
jjyeah
一般會員


發表:10
回覆:11
積分:4
註冊:2002-06-27

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-01-07 22:06:18 IP:61.58.xxx.xxx 未訂閱
我接觸delphi也有大概3,4年了吧! 一開始是因為厭倦了vb每次呼叫dll都出錯開始, 但一直到現在由於自己能力有限(太笨) 也沒寫出什麼像樣的作品 然而 在日常生活中 在辦公室中 很多時候, 一些小軟體雖然不起眼 但確給很多上班族很多方便 比如說: 1.acdsee:大家在講到看圖軟體都離不開他吧! 2.winzip:同上 前陣子剛退伍時我有一個構想, 我想寫個傳真軟體? 也許大家會覺得很好笑,但我是認真的 WinFax Pro 一套幾仟塊 但是我個人覺得不好用 整個操作不附合台灣人的習慣(這是事實) 試想如果在辦公室裡有一套傳真軟體 任何人想要傳真某些文件時,(雖然現在有e-mail,但傳真使用率還很大) 只要在word裡按個傳真鍵, 那這份資料就經由傳真伺服器傳真出去 不必等候在傳真機前 如此是否有利機呢? 這只是我的一個想法而已!
flyup
資深會員


發表:280
回覆:508
積分:385
註冊:2002-04-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-01-07 22:22:38 IP:61.225.xxx.xxx 未訂閱
基於FAX/MODEM遠程通信程序設計    1. 引 言     FAX/MODEM首先用於傳真業務,近幾年發展極為迅速,取得了極大成功。隨著技術的發展和人們認識的提高,人們拓寬了FAX/MODEM的功能,把它用於廣域網路通信中,FAX/MODEM能從微機接受串行資料,直接傳給另一端的FAX機或另一台FAX/MODEM,所以使用微機通過程控電話網和FAX/MODEM互聯起來可以組成一個廣域網路系統,當兩台微機撥號聯上後,它們就獨佔了一條電話線路,它們之間就像本地通信一樣(光電傳輸速度108米/秒)方便[1]。    2. Windows事件驅動編程原理    2.1 WM_COMMNOTIFY消息 WM_COMMNOTIFY是視窗管理類型消息,當COM端口有事件發生時Windows就向視窗發送這條消息。該消息指出了WINDOWS發送接收隊列的狀態,如果通告狀態是CN_EVENT,表明COM端口有通信事件發生,其消息TMessage結構的成員wParam標誌發生事件的COM端口[2]。 2.2 對消息的響應 定義一個視窗及一個消息響應成員函數如下: class TMonitorWindow:public Twindow {//私有成員 public; //公有成員 virtual void WMCommnotify(RTMessage Msg) =〔WM_FIRST:WM_COMMNOTIFY];}; 在此例中,當TMonitorWindow對像接到一個WM_COMMNOTIFY消息,就立即自動喚起WMCOmmnotify成員函數,處理端口事件。其中Msg是消息RTMessage類型的變量,RTMessage是TMessage的引用。從WINDOWS發送的消息信息存放於Msg中。 如果表達式(((Msg.LP.Lo& CN_EVENT)==CN_EVENT)&&(Msg.WParam==comm2))為真,則表明端口comm2有通信事件發生,可以從comm2中讀取接收報文。    3. FAX/MODEM的控制    3.1 命令模式和在線模式 FAX/MODEM工作時處在本地命令狀態或在線狀態。處在本地命令時,用戶能夠通過計算機的串行接口向它發送命令,完成一定功能,FAX/MODEM不傳送這些命令;一旦與遠程FAX/MODEM建立連接後,FAX/MODEM就進入在線狀態,這時它將直接傳送計算機發送的命令[1]。 3.2 命令和結果碼 所有HayesFAX/MODEM控制命令毫無例外一律使用AT開頭。當FAX/MODEM接受一個命令,它就返回一個結果,這個結果可以是一個字符串或結果碼。因此可以編程與FAX/MODEM交互,實現用軟體來控制FAX/MODEM。    4.遠程監視編程     假設2台微機(稱A和B)通過電話網、FAX/MODEM連接,用A機監視B機,實時接收B機發送的狀態報文(B機的發送是隨機的),那麼A機的監視軟體模塊主要包括:定義監視視窗;初始化並建立與B機的連接;監視B機;掛斷關閉通信口結束程序執行。這裡介紹功能模塊編程方法如下: 4.1 定義監視視窗 class TMonitorWindow: public TWindow { COMSTAT comstat; char buffer[1024]; ∥緩衝區 int bufnum; ∥緩衝區實際字節數 int comdev; ∥串行口設備號 int status;  ∥當前通信狀態 void InitComm(); ∥初始化串行口 void InitFAX/MODEM();∥初始化FAX/MODEM void Dial(char*);  ∥撥號 void Connect();  ∥接聽電話 void HangUp();   ∥掛斷電話 void EndFAX/MODEM(); ∥掛斷FAX/MODEM void EndComm();  ∥結束通信 int ReadFAX/MODEMCode();∥讀取FAX/MODEM返回碼public: TMonitorWindow(PTWindowsObject AParent, LPSTR ATitle); virtual void CloseWindow(); virtual void WMClose(RTMessage Msg) =〔CM_FIRST+WM_CLOSE];∥終止程序執行 virtual void CommMessage(RTMessage Msg) =〔WM_FIRST+WM_COMMNOTIFY;∥通信消息函數 }; 4.2 初始化並建立與B機的連接 4.2.1 計算機串口初始化 串行口的初始化必須完成三項任務:一調用OpenComm函數打開串行口。一個重要的工作是檢查返回值,如果小於或等於0,則打開操作失敗,這時必須採取容錯措施;二調用SetCommState設置通信參數;三是調用函數setCommEventMask設定視窗只收CN_EVENT通告;調用函數 EnableCommNotification屏蔽 CN_RECEIVE和CN_TRANSMIT通告。參考程式碼如下: void TMonitorWindow::InitComm() {  DCB dcb;  comdev=OpenComm(〞COM3〞,1024.1024);  if(comdev<=0)  {  MessageBox(HWindow,〞串行口打開失敗!〞 ,〞出錯〞,MB_OK);  GetCommError(comdev,&comstat);  }  else  {  GetCommState(comdev,&dcb); dcb.BaudRate=4800;  dcb.Parity=NOPARITY;  dcb.ByteSize=8;  dcb.StopBits=ONESTOPBIT;  if (SetCommState(&dcb)<0) { McssagcBox(HWindow,〞串行口打開失敗!〞 ,〞出錯〞,MB_OK); GetCommError(comdev,&comstat); return; } SetCommEventMask(comdev,EV_RXCHAR |EV_RING |EV_BREAK); EnableCommNotification(comdev,HWindow,-1,-1); } } 4.2.2 FAX/MODEM初始化 作如下工作:關掉螢幕回顯,設置數字顯示結果碼,打開載波信號,設置揚聲器值,打開結果碼,設置FAX/MODEM值。組合命令為: 〞ATEOVO&C1&D2X4M1L1QOSO=OS7=10\r〞; 參考程式碼如下: void TMonitorWindow::InitFAX/MODEM() { char *Str=〞ATEOVO&C1&D2X4M1L1QOSO=OS7=10\r〞; if (WriteComm(comdev,Str,strlen(Str))<0) { GetCommError(comdev,&comstat); MessageBox(HWindow,〞初使化FAX/MODEM失敗!〞,〞出錯〞,MB_OK); } } 4.2.3 撥號 如果用音頻撥號方式撥電話號碼1234567,撥號命令為: 「ATDT 1234567\r」; 如果用脈衝撥號方式撥電話號碼1234567,撥號命令為: 「ATDP 1234567\r」; 如果電話號碼暫存到字符串DialStr中,用Dial函數撥號,參考程式碼如下: void TMonitorWindow::Dial(char *telphone) { char DialStr[50]; sprintf(DialStr,〞ATDP%s\r〞,telphone); if(WriteComm(comdev,DialStr,strlen(DialStr))<0) { MessageBox(HWindow,〞撥號FAX/MODEM失敗!〞,〞出錯〞,MB_OK); GetCommError(comdev,&comstat); } } 4.2.4 連接 發送〞ATA\r〞命令可以實現連接。 參考程式碼如下: void TMonitorWindow::Conncct() { char* connstr=〞ATA\r〞; if(WriteComm(comdev,connstr,strlen(connstr))<0) { MessageBox(HWindow,〞撥號FAX/MODEM失敗!〞,〞出錯〞,MB_OK); GetCommError(comdev,&comstat); } } 4.3 監視B機 4.3.1 讀FAX/MODEM返回碼 計算機向FAX/MODEM發送命令後,立即讀通信口的接送隊列,將讀出的字符串轉換成整數即得到FAX/MODEM返回碼。參考程式碼如下: int TMonitorWindow::ReadFAX/MODEMCode() { char tempbuf[20] int readno; readno=ReadComm(comdev,tempbuf,3); if (readno<0) { MessageBox(HWindow,〞Read FAX/MODEM CodeError!〞,〞ERROR〞,MB_OK); GetCommError(comdev,&comstat); return -1; } else { tempbuf[readno]=′\0′; return(atoi(tempbuf)); } } 4.3.2 監控FAX/MODEM WM_COMMNOTIFY消息響應函數參考程式碼如下,其中必須調用函數GetCommEventMask將標誌復位以便能繼續收到通知,調用ReadComm讀接收字符串,並將收到的字符串組合起來,以字符′\0′為結束符。 void TMonitorWindow::CommMessage(RTMessage Msg) { int result; ∥記錄FAX/MODEM返回碼 int event; HDC hdc; MSG msg; if ( ((Msg.LP.Lo & CN_EVENT)==CN_EVENT)&& (Msg.WParam==comdev))∥是通信事件 { event=GetCommEventMask(comdev,EV_RXCHAR); switch (status) { case strdialing: ∥字符串發送撥號 result=ReadFAX/MODEMCode(); if (result==10) {status=strsending; MessageBox(HWindow,〞result=CONNECT〞,〞SEND〞,MB_OK); writcComm(comdcv,buffor,bufnum); } else { if (result) {MessageBox(HWindow,Message[result],〞出錯〞,MB_OK); status=ready; } } break; case strconnecting; ∥字符串電話接聽 result=ReadFAX/MODEMCode(); if (result==1)status=strconnecting; else { if(result) {MessageBox(HWindow,Message[result],〞出錯〞,MB_OK status=ready; } else status=strreceiving; } break; case strsending: HangUp(); break; case strreceiving; ∥收到字符串 bufnum=ReadComm(comdev,buffer,500); if(bufnum>0) { static int i=1; buffer[bufnum]=′\0′; hdc=GetDC(HWindow); TextOut(hdc,10,20*i,buffer,bufnum); ReleaseDC(HWindow,hdc); i++; } else MessageBox(HWindow,〞Receive Error〞,〞ERROR〞,MB_OK); break; case ready: result=ReadFAX/MODEMCode(); status=strconnecting; Connect(); break; default; result=ReadFAX/MODEMCode(); }∥switch } } } } } 4.4 中止程序執行 按Alt+F4,選擇彈出菜單「關閉」項執行「中止程序執行」操作,具體完成「掛斷」、「關閉MODEM」、「關閉串行口」和「關閉監視視窗」功能。 4.4.1 掛斷 發送「ATHO\r」命令可以實現連接。 參考程式碼如下: void TMonitorWindow::HangUp() { char* HangUpstr=〞ATHO\r〞; WriteComm(comdev,HangUpstr,strlen(HangUpstr)); } ---------------- 局局棋盤步步新, 變化無常平常待。 人生相處平常心, 無憂無慮心事成。 ----------------
chih
版主


發表:48
回覆:1186
積分:639
註冊:2002-04-02

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-01-08 08:09:23 IP:211.74.xxx.xxx 未訂閱
感謝flyup的分享...看他的範例好像是BCB..不知道有哪位大大能幫忙翻成Delphi版本ㄋ?? THANKS..
引言: 基於FAX/MODEM遠程通信程序設計 . . .
新手上路1234
一般會員


發表:3
回覆:24
積分:15
註冊:2002-12-27

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-01-08 12:36:26 IP:61.218.xxx.xxx 未訂閱
引言: 感謝flyup的分享...看他的範例好像是BCB..不知道有哪位大大能幫忙翻成Delphi版本ㄋ?? THANKS..
.1 WM_COMMNOTIFY消息 WM_COMMNOTIFY是視窗管理類型消息,當COM端口有事件發生時Windows就向視窗發送這條消息。該消息指出了WINDOWS發送接收隊列的狀態,如果通告狀態是CN_EVENT,表明COM端口有通信事件發生,其消息TMessage結構的成員wParam標誌發生事件的COM端口[2]。 2.2 對消息的響應 定義一個視窗及一個消息響應成員函數如下: TMonitorWindow=CLASS(TFORM) private //私有成員 public //公有成員 procedure WMCommnotify(var Msg:Tmessage) message WM_COMMNOTIFY; end; 在此例中,當TMonitorWindow對像接到一個WM_COMMNOTIFY消息,就立即自動喚起WMCOmmnotify成員函數,處理端口事件。其中Msg是消息RTMessage類型的變量,RTMessage是TMessage的引用。從WINDOWS發送的消息信息存放於Msg中。 如果表達式(((Msg.LP.Lo& CN_EVENT)==CN_EVENT)&&(Msg.WParam==comm2))為真,則表明端口comm2有通信事件發生,可以從comm2中讀取接收報文。 . . . 4.遠程監視編程 假設2台微機(稱A和B)通過電話網、FAX/MODEM連接,用A機監視B機,實時接收B機發送的狀態報文(B機的發送是隨機的),那麼A機的監視軟體模塊主要包括:定義監視視窗;初始化並建立與B機的連接;監視B機;掛斷關閉通信口結束程序執行。這裡介紹功能模塊編程方法如下: 4.1 定義監視視窗 TMonitorWindow=class( TForm) comstat:COMSTAT; buffer:ayyay[0..1023] of char; //緩衝區 bufnum:integer; //緩衝區實際字節數 comdev:integer; //串行口設備號 status:integer; //當前通信狀態 procedure InitComm; //初始化串行口 procedure InitFAX_MODEM; //初始化FAX/MODEM procedure Dial(Number:Pchar); //撥號 procedure Connect; // 接聽電話 procedure HangUp; //掛斷電話 procedure EndFAX_MODEM(); //掛斷FAX/MODEM procedure EndComm; //結束通信 Function ReadFAX_MODEMCode:integer; //讀取FAX/MODEM返回碼public: Procedure CloseWindow; virtual; procedure WMClose(var Msg:Tmessage) message CM_FIRST WM_CLOSE; procedure CommMessage(var Msg:Tmessage) message WM_FIRST WM_COMMNOTIFY; end; . . . procedure TMonitorWindow.InitComm; var DCB dcb; begin comdev:=OpenComm(〞COM3〞,1024.1024); if comdev<=0 then begin MessageBox(handle,'串行口打開失敗!','出錯',MB_OK); GetCommError(comdev,@comstat); end else begin GetCommState(comdev,@dcb); dcb.BaudRate:=4800; dcb.Parity:=NOPARITY; dcb.ByteSize:=8; dcb.StopBits:=ONESTOPBIT; if SetCommState(@dcb)<0 then begin McssagcBox(Handle,'串行口打開失敗!','出錯',MB_OK); GetCommError(comdev,@comstat); exit; end; SetCommEventMask(comdev,EV_RXCHAR OR EV_RING OR EV_BREAK); EnableCommNotification(comdev,Handle,-1,-1); end; 待續.......
系統時間:2024-11-22 23:37:26
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!