從基本面開始吧! |
|
jjyeah
一般會員 發表:10 回覆:11 積分:4 註冊:2002-06-27 發送簡訊給我 |
我接觸delphi也有大概3,4年了吧!
一開始是因為厭倦了vb每次呼叫dll都出錯開始,
但一直到現在由於自己能力有限(太笨)
也沒寫出什麼像樣的作品
然而
在日常生活中
在辦公室中
很多時候, 一些小軟體雖然不起眼
但確給很多上班族很多方便
比如說:
1.acdsee:大家在講到看圖軟體都離不開他吧!
2.winzip:同上 前陣子剛退伍時我有一個構想, 我想寫個傳真軟體?
也許大家會覺得很好笑,但我是認真的
WinFax Pro 一套幾仟塊
但是我個人覺得不好用
整個操作不附合台灣人的習慣(這是事實)
試想如果在辦公室裡有一套傳真軟體
任何人想要傳真某些文件時,(雖然現在有e-mail,但傳真使用率還很大)
只要在word裡按個傳真鍵,
那這份資料就經由傳真伺服器傳真出去
不必等候在傳真機前
如此是否有利機呢? 這只是我的一個想法而已!
|
flyup
資深會員 發表:280 回覆:508 積分:385 註冊:2002-04-15 發送簡訊給我 |
基於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 發送簡訊給我 |
|
新手上路1234
一般會員 發表:3 回覆:24 積分:15 註冊:2002-12-27 發送簡訊給我 |
引言: 感謝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; 待續....... |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |