-rw-r--r-- | T42Frame.cpp | 1212 |
1 files changed, 1212 insertions, 0 deletions
diff --git a/T42Frame.cpp b/T42Frame.cpp new file mode 100644 index 0000000..96bc522 --- a/dev/null +++ b/T42Frame.cpp | |||
@@ -0,0 +1,1212 @@ | |||
1 | // T42Frame.cpp : implementation file | ||
2 | // | ||
3 | |||
4 | #include "stdafx.h" | ||
5 | #include "T42.h" | ||
6 | #include "T42Frame.h" | ||
7 | |||
8 | #include "T42View.h" | ||
9 | #include "CalleeDlg.h" | ||
10 | #include "shared-code/RegEx.h" | ||
11 | #include "T42Document.h" | ||
12 | |||
13 | #include <snmp.h> | ||
14 | |||
15 | #ifdef _DEBUG | ||
16 | #define new DEBUG_NEW | ||
17 | #undef THIS_FILE | ||
18 | static char THIS_FILE[] = __FILE__; | ||
19 | #endif | ||
20 | |||
21 | ///////////////////////////////////////////////////////////////////////////// | ||
22 | // T42Frame | ||
23 | |||
24 | IMPLEMENT_DYNCREATE(T42Frame, CFrameWnd) | ||
25 | |||
26 | T42Frame::T42Frame() | ||
27 | { | ||
28 | VERIFY(m_hNormal=AfxGetApp()->LoadIcon(IDR_T42FRAME)); | ||
29 | VERIFY(m_hFullCup=AfxGetApp()->LoadIcon(IDR_FULLT42)); | ||
30 | |||
31 | m_bTrayMinimize = TRUE; | ||
32 | m_bSleepMinimize = TRUE; | ||
33 | m_bMinimizeSleep = TRUE; | ||
34 | m_onWake = wakeSound|wakePopup; | ||
35 | LoadLayout(); | ||
36 | |||
37 | m_bHaveFocus = FALSE; | ||
38 | m_bTrayed = FALSE; | ||
39 | m_bSleep = FALSE; | ||
40 | |||
41 | m_asyncHandle = NULL; | ||
42 | m_resolveHandle = NULL; | ||
43 | m_ctlSocket = INVALID_SOCKET; | ||
44 | m_Socket = INVALID_SOCKET; | ||
45 | m_localEC.m_cErase = 0177; | ||
46 | m_localEC.m_kill = 025; // ^U | ||
47 | m_localEC.m_wErase = 027;// ^W | ||
48 | m_bEstablished = FALSE; | ||
49 | |||
50 | CleanUp(); | ||
51 | } | ||
52 | |||
53 | T42Frame::~T42Frame() | ||
54 | { | ||
55 | } | ||
56 | |||
57 | BEGIN_MESSAGE_MAP(T42Frame, CFrameWnd) | ||
58 | //{{AFX_MSG_MAP(T42Frame) | ||
59 | ON_WM_CLOSE() | ||
60 | ON_COMMAND(ID_TALK_REMOTEUSER, OnTalkRemoteuser) | ||
61 | ON_MESSAGE(WM_INITIATETALK, OnInitiateTalk) | ||
62 | ON_MESSAGE(WM_TARGETRESOLVED, OnTargetResolved) | ||
63 | ON_MESSAGE(WM_SOURCERESOLVED, OnSourceResolved) | ||
64 | ON_WM_TIMER() | ||
65 | ON_MESSAGE(WM_CTLTRANSACT, OnCTLTransact) | ||
66 | ON_MESSAGE(WM_LOOKUP_SUCCESS, OnLookupSuccess) | ||
67 | ON_MESSAGE(WM_LOOKUP_FAILURE, OnLookupFailure) | ||
68 | ON_MESSAGE(WM_ANNOUNCE_SUCCESS, OnAnnounceSuccess) | ||
69 | ON_MESSAGE(WM_ANNOUNCE_FAILURE, OnAnnounceFailure) | ||
70 | ON_MESSAGE(WM_LEAVEINVITE_SUCCESS, OnLeaveInviteSuccess) | ||
71 | ON_MESSAGE(WM_LEAVEINVITE_FAILURE, OnLeaveInviteFailure) | ||
72 | ON_MESSAGE(WM_TALKACCEPT, OnTalkAccept) | ||
73 | ON_MESSAGE(WM_LOCAL_REMOVE_SUCCESS, OnLocalRemoveSuccess) | ||
74 | ON_MESSAGE(WM_LOCAL_REMOVE_FAILURE, OnLocalRemoveFailure) | ||
75 | ON_MESSAGE(WM_REMOTE_REMOVE_SUCCESS, OnRemoteRemoveSuccess) | ||
76 | ON_MESSAGE(WM_REMOTE_REMOVE_FAILURE, OnRemoteRemoveFailure) | ||
77 | ON_MESSAGE(WM_TALK, OnTalk) | ||
78 | ON_MESSAGE(WM_TALKCHAR, OnTalkChar) | ||
79 | ON_MESSAGE(WM_TALKCONNECT, OnTalkConnect) | ||
80 | ON_WM_CREATE() | ||
81 | ON_UPDATE_COMMAND_UI(ID_INDICATOR_DATE, OnUpdateDate) | ||
82 | ON_MESSAGE(WM_EXITMENULOOP, OnExitMenuLoop) | ||
83 | ON_WM_DESTROY() | ||
84 | ON_WM_SYSCOMMAND() | ||
85 | ON_MESSAGE(WM_NAMERESOLVED, OnNameResolved) | ||
86 | ON_MESSAGE(WM_IPRESOLVED, OnIPResolved) | ||
87 | ON_WM_ACTIVATE() | ||
88 | ON_MESSAGE(WM_TRAYICON, OnTrayIcon) | ||
89 | ON_UPDATE_COMMAND_UI(ID_WINDOW_HIDEINTRAYONMINIMIZE, OnUpdateWindowHideintrayonminimize) | ||
90 | ON_COMMAND(ID_WINDOW_HIDEINTRAYONMINIMIZE, OnWindowHideintrayonminimize) | ||
91 | ON_COMMAND(ID_TALK_ABORT, OnTalkAbort) | ||
92 | ON_UPDATE_COMMAND_UI(ID_TALK_ABORT, OnUpdateTalkAbort) | ||
93 | ON_COMMAND(ID_TALK_RECONNECT, OnTalkReconnect) | ||
94 | ON_UPDATE_COMMAND_UI(ID_TALK_RECONNECT, OnUpdateTalkReconnect) | ||
95 | ON_UPDATE_COMMAND_UI(ID_TALK_REMOTEUSER, OnUpdateTalkRemoteuser) | ||
96 | ON_UPDATE_COMMAND_UI(ID_SLEEP_SLEEP, OnUpdateSleepSleep) | ||
97 | ON_COMMAND(ID_SLEEP_SLEEP, OnSleepSleep) | ||
98 | ON_UPDATE_COMMAND_UI(ID_SLEEP_SLEEPONMINIMIZE, OnUpdateSleepSleeponminimize) | ||
99 | ON_COMMAND(ID_SLEEP_SLEEPONMINIMIZE, OnSleepSleeponminimize) | ||
100 | ON_UPDATE_COMMAND_UI(ID_SLEEP_WAKEUPACTION_MAKESOUND, OnUpdateSleepWakeupactionMakesound) | ||
101 | ON_COMMAND(ID_SLEEP_WAKEUPACTION_MAKESOUND, OnSleepWakeupactionMakesound) | ||
102 | ON_UPDATE_COMMAND_UI(ID_SLEEP_WAKEUPACTION_POPUP, OnUpdateSleepWakeupactionPopup) | ||
103 | ON_COMMAND(ID_SLEEP_WAKEUPACTION_POPUP, OnSleepWakeupactionPopup) | ||
104 | ON_UPDATE_COMMAND_UI(ID_SLEEP_MINIMIZEONSLEEP, OnUpdateSleepMinimizeonsleep) | ||
105 | ON_COMMAND(ID_SLEEP_MINIMIZEONSLEEP, OnSleepMinimizeonsleep) | ||
106 | ON_COMMAND(ID_TALK_CLOSE, OnTalkClose) | ||
107 | //}}AFX_MSG_MAP | ||
108 | END_MESSAGE_MAP() | ||
109 | |||
110 | ///////////////////////////////////////////////////////////////////////////// | ||
111 | // T42Frame message handlers | ||
112 | |||
113 | void T42Frame::OnClose() | ||
114 | { | ||
115 | if(GetKeyState(VK_SHIFT)&0x8000){ | ||
116 | T42Document* pDoc = (T42Document*)GetActiveDocument(); | ||
117 | ASSERT_KINDOF(T42Document,pDoc); | ||
118 | pDoc->AutosaveLayout(); | ||
119 | } | ||
120 | CFrameWnd::OnClose(); | ||
121 | } | ||
122 | |||
123 | BOOL T42Frame::PreCreateWindow(CREATESTRUCT& cs) | ||
124 | { | ||
125 | CWinApp* app = AfxGetApp(); | ||
126 | ASSERT(app); | ||
127 | cs.x = app->GetProfileInt("T42Window","X",cs.x); | ||
128 | cs.y = app->GetProfileInt("T42Window","Y",cs.y); | ||
129 | cs.cx = app->GetProfileInt("T42Window","Width",cs.cx); | ||
130 | cs.cy = app->GetProfileInt("T42Window","Height",cs.cy); | ||
131 | |||
132 | BOOL rv = CFrameWnd::PreCreateWindow(cs); | ||
133 | |||
134 | //cs.style&=~FWS_PREFIXTITLE; | ||
135 | //cs.style|=FWS_ADDTOTITLE; | ||
136 | |||
137 | return rv; | ||
138 | } | ||
139 | |||
140 | void T42Frame::OnTalkRemoteuser() | ||
141 | { | ||
142 | CCalleeDlg callee(this); | ||
143 | callee.m_Callee = m_Target; | ||
144 | callee.m_Caller = m_LocalUser; | ||
145 | callee.m_TTY = m_TargetTTY; | ||
146 | if(callee.DoModal() == IDOK){ | ||
147 | m_Target = callee.m_Callee; | ||
148 | m_LocalUser = callee.m_Caller; | ||
149 | m_TargetTTY = callee.m_TTY; | ||
150 | PostMessage(WM_INITIATETALK); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | LRESULT T42Frame::OnInitiateTalk(WPARAM,LPARAM) | ||
155 | { | ||
156 | if( | ||
157 | (!((T42Document*)GetActiveDocument())->m_bHidden) | ||
158 | && !m_bTrayed | ||
159 | ) | ||
160 | SetForegroundWindow(); | ||
161 | CRegEx atRE, bangRE; | ||
162 | VERIFY(atRE.Compile("([-À-ßà-ÿ[:alnum:]_.]+)@([-[:alnum:].]+)",CRegEx::regExtended));// u, h | ||
163 | VERIFY(bangRE.Compile("([-[:alnum:].]+)[!:]([-À-ßà-ÿ[:alnum:]._]+)",CRegEx::regExtended));// h, u | ||
164 | if(atRE.Match(m_Target,CRegEx::regExtended)){ | ||
165 | m_TargetUser = atRE.GetMatch(1); | ||
166 | m_TargetHost = atRE.GetMatch(2); | ||
167 | }else if(bangRE.Match(m_Target,CRegEx::regExtended)){ | ||
168 | m_TargetUser = bangRE.GetMatch(2); | ||
169 | m_TargetHost = bangRE.GetMatch(1); | ||
170 | }else{ | ||
171 | ShowMessage(IDS_ERR_MALFORMEDREMOTE,MB_ICONSTOP|MB_OK); | ||
172 | return -1; | ||
173 | } | ||
174 | SetPeerName(); | ||
175 | memset(&m_TargetAddr,0,sizeof(m_TargetAddr)); | ||
176 | m_TargetAddr.sin_addr.s_addr = inet_addr(m_TargetHost); | ||
177 | if(m_TargetAddr.sin_addr.s_addr == INADDR_NONE){ | ||
178 | StatusLine(IDS_STATUS_RESOLVING); | ||
179 | m_asyncHandle = WSAAsyncGetHostByName( | ||
180 | m_hWnd,WM_TARGETRESOLVED, | ||
181 | (LPCTSTR)m_TargetHost, | ||
182 | (char*)m_gethostData,sizeof(m_gethostData) | ||
183 | ); | ||
184 | if(!m_asyncHandle){ | ||
185 | WSSystemMessage(IDS_ERR_REMOTERESOLVEFAILED,WSAGetLastError()); | ||
186 | return -1; | ||
187 | } | ||
188 | // Here we're trying to establish connection using hostname (as opposed | ||
189 | // to ip address) - no further investigation needed. | ||
190 | AddToHotList(); | ||
191 | }else{ | ||
192 | if(!Klever::FindIFace(m_TargetAddr.sin_addr,m_SourceAddr.sin_addr)) | ||
193 | m_SourceAddr.sin_addr.s_addr = INADDR_ANY; | ||
194 | PostMessage(WM_SOURCERESOLVED); | ||
195 | // Try to resolve hostname if it resolves back to the same IP - this | ||
196 | // is the canonical name we need. If not - leave it as IP. | ||
197 | m_resolveHandle = WSAAsyncGetHostByAddr( | ||
198 | m_hWnd,WM_NAMERESOLVED, | ||
199 | (char*)&m_TargetAddr.sin_addr,sizeof(m_TargetAddr.sin_addr),AF_INET, | ||
200 | (char*)m_ghResolve,sizeof(m_ghResolve) | ||
201 | ); | ||
202 | if(!m_resolveHandle){ | ||
203 | // We've failed to resolve hostname - leave IP - do nothing. | ||
204 | TRACE0("Failed to initiate IP resolve\n"); | ||
205 | AddToHotList(); | ||
206 | } | ||
207 | } | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | LRESULT T42Frame::OnNameResolved(WPARAM,LPARAM lP) | ||
212 | { | ||
213 | m_resolveHandle=NULL; | ||
214 | if(WSAGETASYNCERROR(lP)){ | ||
215 | // We've failed to resolve hostname - leave IP - do nothing. | ||
216 | TRACE0("Failed to resolve name by ip\n"); | ||
217 | AddToHotList(); | ||
218 | }else{ | ||
219 | hostent* he = (hostent*)m_ghResolve; | ||
220 | m_nameFromIP = he->h_name; | ||
221 | m_resolveHandle = WSAAsyncGetHostByName( | ||
222 | m_hWnd,WM_IPRESOLVED, | ||
223 | (LPCTSTR)m_nameFromIP, | ||
224 | (char*)m_ghResolve,sizeof(m_ghResolve) | ||
225 | ); | ||
226 | if(!m_resolveHandle){ | ||
227 | // We've failed to resolve hostname - leave IP - do nothing. | ||
228 | TRACE0("Failed to initiate name resolve\n"); | ||
229 | AddToHotList(); | ||
230 | } | ||
231 | } | ||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | LRESULT T42Frame::OnIPResolved(WPARAM,LPARAM lP) | ||
236 | { | ||
237 | m_resolveHandle=NULL; | ||
238 | if(WSAGETASYNCERROR(lP)){ | ||
239 | // We've failed to resolve hostname - leave IP - do nothing. | ||
240 | TRACE0("Failed to resolve name by ip\n"); | ||
241 | AddToHotList(); | ||
242 | }else{ | ||
243 | hostent* he = (hostent*)m_ghResolve; | ||
244 | if( | ||
245 | he->h_length!=sizeof(m_TargetAddr.sin_addr) | ||
246 | || he->h_addrtype!=m_TargetAddr.sin_family | ||
247 | || memcmp(*he->h_addr_list,&m_TargetAddr.sin_addr,he->h_length) | ||
248 | ){ | ||
249 | // The host resolved to different IP address.. | ||
250 | // maybe we should warn user about it? | ||
251 | TRACE0("IP/NAME investigations sucked in result\n"); | ||
252 | AddToHotList(); | ||
253 | }else{ | ||
254 | // We got new hostname!! Hurray! What do we do? | ||
255 | // Yes, we set new Target.. | ||
256 | m_TargetHost = m_nameFromIP; | ||
257 | m_Target = m_TargetUser + '@' + m_TargetHost; | ||
258 | SetPeerName(); | ||
259 | AddToHotList(); | ||
260 | T42Document* pDoc = (T42Document*)GetActiveDocument(); | ||
261 | ASSERT_KINDOF(T42Document,pDoc); | ||
262 | if(pDoc->m_pRobot) | ||
263 | pDoc->m_pRobot->OnIPResolved(); | ||
264 | TRACE0("IP/NAME investigations succeeded\n"); | ||
265 | } | ||
266 | } | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | LRESULT T42Frame::OnTargetResolved(WPARAM,LPARAM lP) | ||
271 | { | ||
272 | m_asyncHandle=NULL; | ||
273 | if(WSAGETASYNCERROR(lP)){ | ||
274 | WSSystemMessage(IDS_ERR_REMOTERESOLVEFAILED,WSAGetLastError()); | ||
275 | return 0; | ||
276 | } | ||
277 | ASSERT(((hostent*)m_gethostData)->h_length==4); | ||
278 | memmove(&m_TargetAddr.sin_addr,*((hostent*)m_gethostData)->h_addr_list,sizeof(m_TargetAddr.sin_addr)); | ||
279 | if(!Klever::FindIFace(m_TargetAddr.sin_addr,m_SourceAddr.sin_addr)) | ||
280 | m_SourceAddr.sin_addr.s_addr = INADDR_ANY; | ||
281 | PostMessage(WM_SOURCERESOLVED); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | LRESULT T42Frame::OnSourceResolved(WPARAM,LPARAM) | ||
286 | { | ||
287 | // Open ctl socket | ||
288 | m_SourceAddr.sin_port = 0; | ||
289 | m_SourceAddr.sin_family = AF_INET; | ||
290 | m_ctlSocket = socket(AF_INET,SOCK_DGRAM,0); | ||
291 | if(m_ctlSocket==INVALID_SOCKET){ | ||
292 | WSSystemMessage(IDS_ERR_CTLCREATEFAILED,WSAGetLastError()); | ||
293 | return -1; | ||
294 | } | ||
295 | if(bind(m_ctlSocket,(sockaddr*)&m_SourceAddr,sizeof(m_SourceAddr))){ | ||
296 | WSSystemMessage(IDS_ERR_CTLBINDFAILED,WSAGetLastError()); | ||
297 | return -1; | ||
298 | } | ||
299 | int length = sizeof(m_ctlAddr); | ||
300 | if(getsockname(m_ctlSocket,(sockaddr*)&m_ctlAddr,&length)){ | ||
301 | WSSystemMessage(IDS_ERR_CTLGETFAILED,WSAGetLastError()); | ||
302 | return -1; | ||
303 | } | ||
304 | // Open socket for connection | ||
305 | m_SourceAddr.sin_port = 0; | ||
306 | m_SourceAddr.sin_family = AF_INET; | ||
307 | m_Socket = socket(AF_INET,SOCK_STREAM,0); | ||
308 | if(m_Socket==INVALID_SOCKET){ | ||
309 | WSSystemMessage(IDS_ERR_TCPCREATEFAILED,WSAGetLastError()); | ||
310 | return -1; | ||
311 | } | ||
312 | if(bind(m_Socket,(sockaddr*)&m_SourceAddr,sizeof(m_SourceAddr))){ | ||
313 | WSSystemMessage(IDS_ERR_TCPBINDFAILED,WSAGetLastError()); | ||
314 | return -1; | ||
315 | } | ||
316 | length = sizeof(m_SourceAddr); | ||
317 | if(getsockname(m_Socket,(sockaddr*)&m_SourceAddr,&length)){ | ||
318 | WSSystemMessage(IDS_ERR_TCPGETFAILED,WSAGetLastError()); | ||
319 | return -1; | ||
320 | } | ||
321 | StatusLine(IDS_STATUS_LOOKUPINVITE); | ||
322 | TalkCtlMessage rq; | ||
323 | FillInMessage(rq); | ||
324 | rq.m_Type = talkCtlReqLookUp; | ||
325 | m_TargetAddr.sin_family = AF_INET; | ||
326 | CT42App* app = (CT42App*)AfxGetApp(); | ||
327 | m_TargetAddr.sin_port = htons(app->m_T42TalkPort); | ||
328 | VERIFY(AsyncCtlTransact(rq,m_TargetAddr,WM_LOOKUP_SUCCESS,WM_LOOKUP_FAILURE)); | ||
329 | return 0; | ||
330 | } | ||
331 | |||
332 | BOOL T42Frame::FillInMessage(TalkCtlMessage& msg) | ||
333 | { | ||
334 | memset(&msg,0,sizeof(msg)); | ||
335 | msg.m_Version = talkCtlVersion; | ||
336 | msg.m_Addr = m_SourceAddr; | ||
337 | msg.m_ctlAddr = m_ctlAddr; | ||
338 | msg.m_ID = htonl(0); | ||
339 | msg.m_PID = htonl((LONG)m_hWnd); | ||
340 | ASSERT(m_LocalUser.GetLength()>0 && m_LocalUser.GetLength()<sizeof(msg.m_LName)); | ||
341 | strcpy(msg.m_LName,m_LocalUser); | ||
342 | ASSERT(m_TargetUser.GetLength()>0 && m_TargetUser.GetLength()<sizeof(msg.m_RName)); | ||
343 | strcpy(msg.m_RName,m_TargetUser); | ||
344 | ASSERT(m_TargetTTY.GetLength()>=0 && m_TargetTTY.GetLength()<sizeof(msg.m_RTTY)); | ||
345 | strcpy(msg.m_RTTY,m_TargetTTY); | ||
346 | return TRUE; | ||
347 | } | ||
348 | |||
349 | BOOL T42Frame::AsyncCtlTransact(TalkCtlMessage& msg,sockaddr_in& target, UINT wmSuccess,UINT wmFailure) | ||
350 | { | ||
351 | if(m_ctlSuccess || m_ctlFailure) | ||
352 | return FALSE; | ||
353 | memmove(&m_ctlTarget,&target,sizeof(m_ctlTarget)); | ||
354 | memmove(&m_ctlRequest,&msg,sizeof(m_ctlRequest)); | ||
355 | m_ctlSuccess = wmSuccess; | ||
356 | m_ctlFailure = wmFailure; | ||
357 | TRACE2("Initiating CTL Transaction to %s:%d\n", | ||
358 | inet_ntoa(m_ctlTarget.sin_addr),ntohs(m_ctlTarget.sin_port) | ||
359 | ); | ||
360 | TRACE3("V: %d, T: %d, ID: %ld\n", | ||
361 | (int)m_ctlRequest.m_Version, (int)m_ctlRequest.m_Type, | ||
362 | ntohl(m_ctlRequest.m_ID) | ||
363 | ); | ||
364 | TRACE("ADDR: %s:%d\n", | ||
365 | inet_ntoa(((sockaddr_in*)&m_ctlRequest.m_Addr)->sin_addr), | ||
366 | ntohs(((sockaddr_in*)&m_ctlRequest.m_Addr)->sin_port) | ||
367 | ); | ||
368 | TRACE("CTL ADDR: %s:%d\n", | ||
369 | inet_ntoa(((sockaddr_in*)&m_ctlRequest.m_ctlAddr)->sin_addr), | ||
370 | ntohs(((sockaddr_in*)&m_ctlRequest.m_ctlAddr)->sin_port) | ||
371 | ); | ||
372 | if(sendto(m_ctlSocket,(char*)&m_ctlRequest,sizeof(m_ctlRequest),0, | ||
373 | (sockaddr*)&m_ctlTarget,sizeof(m_ctlTarget))!=sizeof(m_ctlRequest) | ||
374 | ){ | ||
375 | AsyncCtlTransactFailed(ctlFailSendto,WSAGetLastError()); | ||
376 | return TRUE; | ||
377 | } | ||
378 | if(WSAAsyncSelect(m_ctlSocket,m_hWnd,WM_CTLTRANSACT,FD_READ)){ | ||
379 | AsyncCtlTransactFailed(ctlFailSelect,WSAGetLastError()); | ||
380 | return TRUE; | ||
381 | } | ||
382 | SetTimer(timerTransact,2000,NULL); | ||
383 | return TRUE; | ||
384 | } | ||
385 | |||
386 | LRESULT T42Frame::OnCTLTransact(WPARAM,LPARAM lP) | ||
387 | { | ||
388 | KillTimer(timerTransact); | ||
389 | if(!(m_ctlSuccess && m_ctlFailure)) | ||
390 | return -1; | ||
391 | if(WSAGETSELECTERROR(lP)){ | ||
392 | AsyncCtlTransactFailed(ctlFailError,WSAGETSELECTERROR(lP)); | ||
393 | return -1; | ||
394 | } | ||
395 | ASSERT(WSAGETSELECTEVENT(lP)&FD_READ); | ||
396 | long length; | ||
397 | do{ | ||
398 | if(ioctlsocket(m_ctlSocket,FIONREAD,(u_long*)&length) || length<=0) | ||
399 | break; | ||
400 | if(recv(m_ctlSocket,(char*)&m_ctlResponse,sizeof(m_ctlResponse),0)!=sizeof(m_ctlResponse)) | ||
401 | continue; | ||
402 | if( | ||
403 | m_ctlResponse.m_Version != talkCtlVersion | ||
404 | || m_ctlResponse.m_Type!=m_ctlRequest.m_Type | ||
405 | ) | ||
406 | continue; | ||
407 | // We got the datagram we need here | ||
408 | AsyncCtlTransactSucceeded(m_ctlResponse); | ||
409 | }while(1); | ||
410 | if(WSAAsyncSelect(m_ctlSocket,m_hWnd,WM_CTLTRANSACT,FD_READ)){ | ||
411 | AsyncCtlTransactFailed(ctlFailSelect,WSAGetLastError()); | ||
412 | return -1; | ||
413 | } | ||
414 | SetTimer(timerTransact,2000,NULL); | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | void T42Frame::OnTimer(UINT nIDEvent) | ||
419 | { | ||
420 | switch(nIDEvent){ | ||
421 | case timerTransact: | ||
422 | KillTimer(timerTransact); | ||
423 | if(!(m_ctlSuccess && m_ctlFailure)){ | ||
424 | TRACE0("VERY STRANGE\n"); | ||
425 | break; | ||
426 | } | ||
427 | TRACE0("Transact timed out\n"); | ||
428 | if(sendto(m_ctlSocket,(char*)&m_ctlRequest,sizeof(m_ctlRequest),0, | ||
429 | (sockaddr*)&m_ctlTarget,sizeof(m_ctlTarget))!=sizeof(m_ctlRequest) | ||
430 | ){ | ||
431 | AsyncCtlTransactFailed(ctlFailSendto,WSAGetLastError()); | ||
432 | break; | ||
433 | } | ||
434 | if(WSAAsyncSelect(m_ctlSocket,m_hWnd,WM_CTLTRANSACT,FD_READ)){ | ||
435 | AsyncCtlTransactFailed(ctlFailSelect,WSAGetLastError()); | ||
436 | break; | ||
437 | } | ||
438 | SetTimer(timerTransact,2000,NULL); | ||
439 | break; | ||
440 | } | ||
441 | |||
442 | CFrameWnd::OnTimer(nIDEvent); | ||
443 | } | ||
444 | |||
445 | |||
446 | void T42Frame::AsyncCtlTransactFailed(UINT code,LONG error) | ||
447 | { | ||
448 | ASSERT(m_ctlSuccess && m_ctlFailure); | ||
449 | UINT m = m_ctlFailure; | ||
450 | m_ctlFailure = m_ctlSuccess = 0; | ||
451 | WSAAsyncSelect(m_ctlSocket,NULL,0,0); | ||
452 | TRACE2("CTL Transact failed %d (%ld)\n",(int)code,error); | ||
453 | PostMessage(m,code,error); | ||
454 | } | ||
455 | |||
456 | void T42Frame::AsyncCtlTransactSucceeded(TalkCtlResponse& response) | ||
457 | { | ||
458 | ASSERT(m_ctlSuccess && m_ctlFailure); | ||
459 | UINT m = m_ctlSuccess; | ||
460 | m_ctlFailure = m_ctlSuccess = 0; | ||
461 | WSAAsyncSelect(m_ctlSocket,NULL,0,0); | ||
462 | TRACE2("CTL Transaction succeeded - A: %d, ID: %ld\n", | ||
463 | (int)response.m_Answer, ntohl(response.m_ID) | ||
464 | ); | ||
465 | TRACE2("ADDR: %s:%d\n", | ||
466 | inet_ntoa(((sockaddr_in*)&response.m_Addr)->sin_addr), | ||
467 | ntohs(((sockaddr_in*)&response.m_Addr)->sin_port) | ||
468 | ); | ||
469 | PostMessage(m,0,(LPARAM)&response); | ||
470 | } | ||
471 | |||
472 | LRESULT T42Frame::OnLookupSuccess(WPARAM,LPARAM lP) | ||
473 | { | ||
474 | TalkCtlResponse& rp = *(TalkCtlResponse*)lP; | ||
475 | if(rp.m_Answer==talkCtlSuccess){ | ||
476 | TRACE0("Found an invitation\n"); | ||
477 | if(WSAAsyncSelect(m_Socket,m_hWnd,WM_TALKCONNECT,FD_CONNECT)){ | ||
478 | WSSystemMessage(IDS_ERR_TCPASELFAILED,WSAGetLastError()); | ||
479 | return -1; | ||
480 | } | ||
481 | SOCKADDR_IN sin; | ||
482 | memmove(&sin,&rp.m_Addr,sizeof(sin)); | ||
483 | sin.sin_family = ntohs(sin.sin_family); | ||
484 | StatusLine(IDS_STATUS_WAITINGTOCONNECT); | ||
485 | if(connect(m_Socket,(sockaddr*)&sin,sizeof(sin))){ | ||
486 | if(WSAGetLastError()!=WSAEWOULDBLOCK){ | ||
487 | WSSystemMessage(IDS_ERR_TCPCONNECTFAILED,WSAGetLastError()); | ||
488 | return -1; | ||
489 | } | ||
490 | }else | ||
491 | PostMessage(WM_TALKCONNECT,0,WSAMAKESELECTREPLY(FD_CONNECT,0)); | ||
492 | }else{ | ||
493 | if(listen(m_Socket,5)){ | ||
494 | WSSystemMessage(IDS_ERR_TCPLISTENFAILED,WSAGetLastError()); | ||
495 | return -1; | ||
496 | } | ||
497 | if(WSAAsyncSelect(m_Socket,m_hWnd,WM_TALKACCEPT,FD_ACCEPT)){ | ||
498 | WSSystemMessage(IDS_ERR_LTNASELFAILED,WSAGetLastError()); | ||
499 | return -1; | ||
500 | } | ||
501 | TalkCtlMessage rq; | ||
502 | FillInMessage(rq); | ||
503 | rq.m_Type = talkCtlReqLeaveInvite; | ||
504 | rq.m_ID = htonl(-1); | ||
505 | SOCKADDR_IN tgt; | ||
506 | memmove(&tgt,&m_SourceAddr,sizeof(tgt)); | ||
507 | CT42App* app = (CT42App*)AfxGetApp(); | ||
508 | tgt.sin_port = htons(app->m_T42TalkPort); | ||
509 | VERIFY(AsyncCtlTransact(rq,tgt,WM_LEAVEINVITE_SUCCESS,WM_LEAVEINVITE_FAILURE)); | ||
510 | } | ||
511 | return 0; | ||
512 | } | ||
513 | LRESULTT42Frame::OnLookupFailure(WPARAM wP,LPARAM lP) | ||
514 | { | ||
515 | SystemMessage(IDS_ERR_CTLLOOKUPFAILED); | ||
516 | TRACE2("Lookup failed %d, %ld",(int)wP,lP); | ||
517 | return -1; | ||
518 | } | ||
519 | |||
520 | LRESULT T42Frame::OnAnnounceSuccess(WPARAM,LPARAM lP) | ||
521 | { | ||
522 | TalkCtlResponse& rp = *(TalkCtlResponse*)lP; | ||
523 | if(rp.m_Answer != talkCtlSuccess){ | ||
524 | static | ||
525 | UINT nReasons[] = {0,IDS_CTL_NOTHERE,IDS_CTL_FAILED,IDS_CTL_MACHUNKNOWN, | ||
526 | IDS_CTL_PERMISSIONDENIED, IDS_CTL_BADREQUEST, IDS_CTL_BADVERSION, | ||
527 | IDS_CTL_BADADDR, IDS_CTL_BADCTL}; | ||
528 | CString reason; | ||
529 | if(rp.m_Answer<(sizeof(nReasons)/sizeof(*nReasons))) | ||
530 | SystemMessage(IDS_ERR_ANNOUNCEFAILURE,nReasons[rp.m_Answer]); | ||
531 | else | ||
532 | SystemMessage(IDS_ERR_ANNOUNCEFAILURE,IDS_CTL_UNKNOWNERROR); | ||
533 | return -1; | ||
534 | } | ||
535 | m_remoteID = rp.m_ID; | ||
536 | return 0; | ||
537 | } | ||
538 | LRESULT T42Frame::OnAnnounceFailure(WPARAM wP,LPARAM lP) | ||
539 | { | ||
540 | SystemMessage(IDS_ERR_ANNOUNCEFAILED); | ||
541 | return -1; | ||
542 | } | ||
543 | |||
544 | LRESULT T42Frame::OnLeaveInviteSuccess(WPARAM,LPARAM lP) | ||
545 | { | ||
546 | TalkCtlResponse& rp = *(TalkCtlResponse*)lP; | ||
547 | m_localID = rp.m_ID; | ||
548 | TalkCtlMessage rq; | ||
549 | FillInMessage(rq); | ||
550 | rq.m_ID = htonl(-1); | ||
551 | StatusLine(IDS_STATUS_ANNOUNCING); | ||
552 | rq.m_Type = talkCtlReqAnnounce; | ||
553 | m_TargetAddr.sin_family = AF_INET; | ||
554 | CT42App* app = (CT42App*)AfxGetApp(); | ||
555 | m_TargetAddr.sin_port = htons(app->m_T42TalkPort); | ||
556 | VERIFY(AsyncCtlTransact(rq,m_TargetAddr,WM_ANNOUNCE_SUCCESS,WM_ANNOUNCE_FAILURE)); | ||
557 | return 0;// Or? | ||
558 | } | ||
559 | LRESULT T42Frame::OnLeaveInviteFailure(WPARAM wP,LPARAM lP) | ||
560 | { | ||
561 | SystemMessage(IDS_ERR_LEAVINVITEFAILED); | ||
562 | TRACE2("LeaveInvite failed %d, %ld",(int)wP,lP); | ||
563 | return -1; | ||
564 | } | ||
565 | |||
566 | LRESULT T42Frame::OnTalkAccept(WPARAM,LPARAM lP) | ||
567 | { | ||
568 | if(WSAGETSELECTERROR(lP)){ | ||
569 | WSSystemMessage(IDS_ERR_TCPACCEPTFAILED,WSAGETSELECTERROR(lP)); | ||
570 | return -1; | ||
571 | } | ||
572 | ASSERT(WSAGETSELECTEVENT(lP)&FD_ACCEPT); | ||
573 | SOCKET s = accept(m_Socket,NULL,NULL); | ||
574 | ASSERT(s!=INVALID_SOCKET); | ||
575 | VERIFY(!closesocket(m_Socket)); | ||
576 | m_Socket = s; | ||
577 | m_bConnected=TRUE; | ||
578 | SelectTalkSocket(); | ||
579 | StatusLine(IDS_STATUS_WAITINGTOCONNECT); | ||
580 | TalkCtlMessage rq; | ||
581 | FillInMessage(rq); | ||
582 | rq.m_Type = talkCtlReqDelete; | ||
583 | rq.m_ID = m_localID; | ||
584 | SOCKADDR_IN t; | ||
585 | memmove(&t,&m_SourceAddr,sizeof(t)); | ||
586 | CT42App* app = (CT42App*)AfxGetApp(); | ||
587 | t.sin_port = htons(app->m_T42TalkPort); | ||
588 | AsyncCtlTransact(rq,t,WM_LOCAL_REMOVE_SUCCESS,WM_LOCAL_REMOVE_FAILURE); | ||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | LRESULT T42Frame::OnTalkConnect(WPARAM,LPARAM lP) | ||
593 | { | ||
594 | if(WSAGETSELECTERROR(lP)){ | ||
595 | WSSystemMessage(IDS_ERR_TCPCONNECTFAILED,WSAGETSELECTERROR(lP)); | ||
596 | return -1; | ||
597 | } | ||
598 | m_bConnected=TRUE; | ||
599 | ASSERT(WSAGETSELECTEVENT(lP)&FD_CONNECT); | ||
600 | SelectTalkSocket(); | ||
601 | StatusLine(IDS_STATUS_WAITINGTOCONNECT); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | LRESULT T42Frame::OnLocalRemoveSuccess(WPARAM,LPARAM lP) | ||
606 | { | ||
607 | TalkCtlResponse& rp = *(TalkCtlResponse*)lP; | ||
608 | ASSERT(rp.m_Answer==talkCtlSuccess); | ||
609 | TalkCtlMessage rq; | ||
610 | FillInMessage(rq); | ||
611 | rq.m_Type = talkCtlReqDelete; | ||
612 | rq.m_ID = m_remoteID; | ||
613 | SOCKADDR_IN t; | ||
614 | memmove(&t,&m_TargetAddr,sizeof(t)); | ||
615 | CT42App* app = (CT42App*)AfxGetApp(); | ||
616 | t.sin_port = htons(app->m_T42TalkPort); | ||
617 | AsyncCtlTransact(rq,t,WM_REMOTE_REMOVE_SUCCESS,WM_REMOTE_REMOVE_FAILURE); | ||
618 | return 0; | ||
619 | } | ||
620 | LRESULT T42Frame::OnLocalRemoveFailure(WPARAM wP,LPARAM lP) | ||
621 | { | ||
622 | //SystemMessage(IDS_ERR_CTLLDELETEFAILED); | ||
623 | TRACE2("Local delete failed %d, %ld",(int)wP,lP); | ||
624 | return -1; | ||
625 | } | ||
626 | |||
627 | LRESULT T42Frame::OnRemoteRemoveSuccess(WPARAM,LPARAM lP) | ||
628 | { | ||
629 | TalkCtlResponse& rp = *(TalkCtlResponse*)lP; | ||
630 | // ASSERT(rp.m_Answer==talkCtlSuccess);// ??? | ||
631 | return 0; | ||
632 | } | ||
633 | LRESULT T42Frame::OnRemoteRemoveFailure(WPARAM wP,LPARAM lP) | ||
634 | { | ||
635 | //SystemMessage(IDS_ERR_CTLRDELETEFAILED); | ||
636 | TRACE2("Local delete failed %d, %ld",(int)wP,lP); | ||
637 | return -1; | ||
638 | } | ||
639 | |||
640 | LRESULT T42Frame::OnTalk(WPARAM wP,LPARAM lP) | ||
641 | { | ||
642 | if(WSAGETSELECTEVENT(lP)&FD_CLOSE){ | ||
643 | StatusLine(IDS_STATUS_CONNECTIONCLOSED); | ||
644 | if(WSAGETSELECTERROR(lP)) | ||
645 | WSSystemMessage(IDS_ERR_CONNECTIONCLOSED,WSAGETSELECTERROR(lP)); | ||
646 | else | ||
647 | SystemMessage(IDS_CONNECTIONCLOSED); | ||
648 | Established(FALSE); | ||
649 | return 0; | ||
650 | } | ||
651 | if(WSAGETSELECTERROR(lP)){ | ||
652 | WSSystemMessage(IDS_ERR_TCPERROR,WSAGETSELECTERROR(lP)); | ||
653 | Established(FALSE); | ||
654 | TRACE1("Error on conversation socket: %ld\n",WSAGETSELECTERROR(lP)); | ||
655 | return -1; | ||
656 | } | ||
657 | if(WSAGETSELECTEVENT(lP)&FD_READ){ | ||
658 | CHAR rb[512+1]; | ||
659 | int rbytes = recv(m_Socket,rb,sizeof(rb)-1,0); | ||
660 | if(rbytes>0){ | ||
661 | if(m_receivedEC<sizeof(m_remoteEC)){ | ||
662 | int ms = min(sizeof(m_remoteEC)-m_receivedEC,rbytes); | ||
663 | memmove( | ||
664 | &((CHAR*)&m_remoteEC)[m_receivedEC],rb,ms | ||
665 | ); | ||
666 | memmove(rb,&rb[ms],sizeof(rb)-ms); | ||
667 | rbytes-=ms; | ||
668 | m_receivedEC+=ms; | ||
669 | // Under some circumstances we can claim connection | ||
670 | // establishment here. | ||
671 | if(m_receivedEC==sizeof(m_remoteEC)){ | ||
672 | StatusLine(IDS_STATUS_ESTABLISHED); | ||
673 | Established(TRUE); | ||
674 | } | ||
675 | } | ||
676 | if(rbytes){ | ||
677 | rb[rbytes]=0; | ||
678 | T42Document* pDoc = (T42Document*)GetActiveDocument(); | ||
679 | ASSERT_KINDOF(T42Document,pDoc); | ||
680 | if(pDoc->m_pRobot) | ||
681 | pDoc->m_pRobot->OnReceive(rb,rbytes); | ||
682 | PutRemote(rb); | ||
683 | if(!m_bHaveFocus){ | ||
684 | SetTheIcon(m_hFullCup); | ||
685 | if(m_bSleep) | ||
686 | WakeUp(); | ||
687 | } | ||
688 | } | ||
689 | } | ||
690 | } | ||
691 | if(WSAGETSELECTEVENT(lP)&FD_WRITE){ | ||
692 | if(!m_bSentEC){ | ||
693 | if(send(m_Socket,(char*)&m_localEC,sizeof(m_localEC),0)!=sizeof(m_localEC)){ | ||
694 | WSSystemMessage(IDS_ERR_TCPERROR,WSAGetLastError()); | ||
695 | Established(FALSE); | ||
696 | }else | ||
697 | m_bSentEC = TRUE; | ||
698 | }else{ | ||
699 | int sb = send(m_Socket,(char*)(LPCTSTR)m_sendBuffer,m_sendBuffer.GetLength(),0); | ||
700 | if(sb<0){ | ||
701 | WSSystemMessage(IDS_ERR_TCPERROR,WSAGetLastError()); | ||
702 | Established(FALSE); | ||
703 | }else | ||
704 | m_sendBuffer = m_sendBuffer.Mid(sb); | ||
705 | } | ||
706 | } | ||
707 | SelectTalkSocket(); | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | void T42Frame::SelectTalkSocket() | ||
712 | { | ||
713 | if(!m_bConnected) | ||
714 | return; | ||
715 | UINT mask = FD_READ|FD_CLOSE; | ||
716 | if(!(m_bSentEC && m_sendBuffer.IsEmpty())) | ||
717 | mask|=FD_WRITE; | ||
718 | if(WSAAsyncSelect(m_Socket,m_hWnd,WM_TALK,mask)){ | ||
719 | WSSystemMessage(IDS_ERR_TCPERROR,WSAGetLastError()); | ||
720 | Established(FALSE); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | BOOL T42Frame::PutRemote(LPCTSTR str) | ||
725 | { | ||
726 | T42View* pView = (T42View*)GetActiveView(); | ||
727 | ASSERT_KINDOF(T42View,pView); | ||
728 | pView->m_remoteCtl.PutString(str); | ||
729 | return TRUE; | ||
730 | } | ||
731 | |||
732 | LRESULT T42Frame::OnTalkChar(WPARAM wP,LPARAM lP) | ||
733 | { | ||
734 | if(wP){ | ||
735 | CHAR c=(CHAR)(wP&0xFF); | ||
736 | // if(c=='\r') | ||
737 | //?? c='\n'; | ||
738 | m_sendBuffer+=c; | ||
739 | }else{ | ||
740 | CString str = (LPCTSTR)lP; | ||
741 | int cr; | ||
742 | while((cr=str.Find('\r'))>=0) | ||
743 | str = str.Left(cr)+str.Mid(cr+1); | ||
744 | m_sendBuffer+=str; | ||
745 | } | ||
746 | SelectTalkSocket(); | ||
747 | return 0; | ||
748 | } | ||
749 | |||
750 | int T42Frame::OnCreate(LPCREATESTRUCT lpCreateStruct) | ||
751 | { | ||
752 | if(CFrameWnd::OnCreate(lpCreateStruct)==-1) | ||
753 | return -1; | ||
754 | // CG: The following block was inserted by 'Status Bar' component. | ||
755 | { | ||
756 | // Create an array for status bar indicators | ||
757 | UINT pIndicators[3] = { ID_SEPARATOR }; | ||
758 | if (!m_wndStatusBar.Create(this) || | ||
759 | !InitStatusBar(pIndicators, 1, 60)) | ||
760 | { | ||
761 | TRACE0("Failed to create Status Bar\n"); | ||
762 | return -1; | ||
763 | } | ||
764 | } | ||
765 | |||
766 | m_wndFake.CreateEx( | ||
767 | 0,AfxRegisterWndClass(0,0,0,0),"",WS_OVERLAPPED, | ||
768 | 0,0,0,0, | ||
769 | NULL,NULL,NULL | ||
770 | ); | ||
771 | |||
772 | return 0; | ||
773 | } | ||
774 | |||
775 | void T42Frame::OnUpdateDate(CCmdUI* pCmdUI) | ||
776 | { | ||
777 | // CG: This function was inserted by 'Status Bar' component. | ||
778 | |||
779 | // Get current date and format it | ||
780 | CTime time = CTime::GetCurrentTime(); | ||
781 | CString strDate = time.Format(_T("%A, %B %d, %y ")); | ||
782 | |||
783 | // BLOCK: compute the width of the date string | ||
784 | CSize size; | ||
785 | { | ||
786 | HGDIOBJ hOldFont = NULL; | ||
787 | HFONT hFont = (HFONT)m_wndStatusBar.SendMessage(WM_GETFONT); | ||
788 | CClientDC dc(NULL); | ||
789 | if (hFont != NULL) | ||
790 | hOldFont = dc.SelectObject(hFont); | ||
791 | size = dc.GetTextExtent(strDate); | ||
792 | if (hOldFont != NULL) | ||
793 | dc.SelectObject(hOldFont); | ||
794 | } | ||
795 | |||
796 | // Update the pane to reflect the current date | ||
797 | UINT nID, nStyle; | ||
798 | int nWidth; | ||
799 | m_wndStatusBar.GetPaneInfo(m_nDatePaneNo, nID, nStyle, nWidth); | ||
800 | m_wndStatusBar.SetPaneInfo(m_nDatePaneNo, nID, nStyle, size.cx); | ||
801 | pCmdUI->SetText(strDate); | ||
802 | pCmdUI->Enable(TRUE); | ||
803 | |||
804 | } | ||
805 | |||
806 | BOOL T42Frame::InitStatusBar(UINT *pIndicators, int nSize, int nSeconds) | ||
807 | { | ||
808 | // CG: This function was inserted by 'Status Bar' component. | ||
809 | |||
810 | // Create an index for the DATE pane | ||
811 | m_nDatePaneNo = nSize++; | ||
812 | pIndicators[m_nDatePaneNo] = ID_INDICATOR_DATE; | ||
813 | |||
814 | m_wndStatusBar.SetTimer(0x1000, nSeconds * 1000, NULL); | ||
815 | |||
816 | return m_wndStatusBar.SetIndicators(pIndicators, nSize); | ||
817 | |||
818 | } | ||
819 | |||
820 | void T42Frame::StatusLine(LPCTSTR str) | ||
821 | { | ||
822 | m_wndStatusBar.SetPaneText(0,m_Status=str); | ||
823 | } | ||
824 | |||
825 | void T42Frame::StatusLine(UINT nID) | ||
826 | { | ||
827 | VERIFY(m_Status.LoadString(nID)); | ||
828 | m_wndStatusBar.SetPaneText(0,m_Status); | ||
829 | } | ||
830 | |||
831 | LRESULT T42Frame::OnExitMenuLoop(WPARAM,LPARAM) | ||
832 | { | ||
833 | m_wndStatusBar.SetPaneText(0,m_Status); | ||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | void T42Frame::OnDestroy() | ||
838 | { | ||
839 | if(m_bTrayed){ | ||
840 | NOTIFYICONDATA nid; | ||
841 | memset(&nid,0,sizeof(nid)); | ||
842 | nid.cbSize=sizeof(nid); | ||
843 | nid.hWnd = m_hWnd; | ||
844 | nid.uID = IDC_TRAYICON; | ||
845 | nid.uFlags = 0; | ||
846 | VERIFY(Shell_NotifyIcon(NIM_DELETE,&nid)); | ||
847 | } | ||
848 | m_wndFake.DestroyWindow(); | ||
849 | CFrameWnd::OnDestroy(); | ||
850 | |||
851 | CleanUp(); | ||
852 | } | ||
853 | |||
854 | void T42Frame::ShowMessage(UINT nID,UINT flags) | ||
855 | { | ||
856 | CString msg; | ||
857 | VERIFY(msg.LoadString(nID)); | ||
858 | ShowMessage(msg,flags); | ||
859 | } | ||
860 | void T42Frame::ShowMessage(LPCTSTR msg,UINT flags) | ||
861 | { | ||
862 | MessageBox(msg,NULL,flags); | ||
863 | } | ||
864 | |||
865 | void T42Frame::Established(BOOL bEstablished) | ||
866 | { | ||
867 | if(!bEstablished) | ||
868 | CleanUp(); | ||
869 | else{ | ||
870 | if( | ||
871 | (!((T42Document*)GetActiveDocument())->m_bHidden) | ||
872 | && !m_bTrayed | ||
873 | ) | ||
874 | SetForegroundWindow(); | ||
875 | } | ||
876 | T42View* pView = (T42View*)GetActiveView(); | ||
877 | ASSERT_KINDOF(T42View,pView); | ||
878 | pView->SetEnable(bEstablished); | ||
879 | |||
880 | BOOL bRobot = (m_bEstablished && !bEstablished) || (bEstablished && !m_bEstablished); | ||
881 | m_bEstablished = bEstablished; | ||
882 | |||
883 | SetPeerName(); | ||
884 | if(bRobot){ | ||
885 | T42Document* pDoc = (T42Document*)pView->GetDocument(); | ||
886 | ASSERT_KINDOF(T42Document,pDoc); | ||
887 | if(pDoc->m_pRobot){ | ||
888 | if(bEstablished) | ||
889 | pDoc->m_pRobot->OnConnect(); | ||
890 | else | ||
891 | pDoc->m_pRobot->OnDisconnect(); | ||
892 | } | ||
893 | } | ||
894 | } | ||
895 | |||
896 | void T42Frame::CleanUp() | ||
897 | { | ||
898 | if(m_resolveHandle){ | ||
899 | WSACancelAsyncRequest(m_resolveHandle); | ||
900 | m_resolveHandle=NULL; | ||
901 | } | ||
902 | if(m_asyncHandle){ | ||
903 | WSACancelAsyncRequest(m_asyncHandle); | ||
904 | m_asyncHandle=NULL; | ||
905 | } | ||
906 | if(m_ctlSocket!=INVALID_SOCKET){ | ||
907 | closesocket(m_ctlSocket); | ||
908 | m_ctlSocket = INVALID_SOCKET; | ||
909 | } | ||
910 | if(m_Socket!=INVALID_SOCKET){ | ||
911 | closesocket(m_Socket); | ||
912 | m_Socket = INVALID_SOCKET; | ||
913 | } | ||
914 | |||
915 | m_Status.LoadString(AFX_IDS_IDLEMESSAGE); | ||
916 | m_localID = m_remoteID = 0; | ||
917 | m_sendBuffer.Empty(); | ||
918 | m_ctlSuccess = 0; | ||
919 | m_ctlFailure = 0; | ||
920 | m_bSentEC = FALSE; | ||
921 | m_receivedEC = 0; | ||
922 | m_bConnected=FALSE; | ||
923 | } | ||
924 | |||
925 | void T42Frame::OnSysCommand(UINT nID, LPARAM lParam) | ||
926 | { | ||
927 | if(nID==SC_MINIMIZE){ | ||
928 | if(m_bTrayMinimize){ | ||
929 | NOTIFYICONDATA nid; | ||
930 | memset(&nid,0,sizeof(nid)); | ||
931 | nid.cbSize=sizeof(nid); | ||
932 | nid.hWnd = m_hWnd; | ||
933 | nid.uID = IDC_TRAYICON; | ||
934 | nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; | ||
935 | nid.uCallbackMessage = WM_TRAYICON; | ||
936 | nid.hIcon =m_hNormal; | ||
937 | CString tip; | ||
938 | GetWindowText(tip); | ||
939 | if(tip.GetLength()>=sizeof(nid.szTip)) | ||
940 | tip = tip.Left(sizeof(nid.szTip)-3)+".."; | ||
941 | strcpy(nid.szTip,(LPCTSTR)tip); | ||
942 | VERIFY(Shell_NotifyIcon(NIM_ADD,&nid)); | ||
943 | CWnd* pWnd = GetNextWindow(); | ||
944 | ShowWindow(SW_HIDE); | ||
945 | pWnd->SetForegroundWindow(); | ||
946 | m_bTrayed=TRUE; | ||
947 | }else | ||
948 | CFrameWnd::OnSysCommand(nID, lParam); | ||
949 | if(m_bSleepMinimize) | ||
950 | m_bSleep=TRUE; | ||
951 | }else | ||
952 | CFrameWnd::OnSysCommand(nID, lParam); | ||
953 | } | ||
954 | |||
955 | void T42Frame::SaveLayout() | ||
956 | { | ||
957 | CWinApp* app = AfxGetApp(); | ||
958 | CRect rc; | ||
959 | GetWindowRect(rc); | ||
960 | app->WriteProfileInt("T42Window","X",rc.left); | ||
961 | app->WriteProfileInt("T42Window","Y",rc.top); | ||
962 | app->WriteProfileInt("T42Window","Width",rc.Width()); | ||
963 | app->WriteProfileInt("T42Window","Height",rc.Height()); | ||
964 | app->WriteProfileInt("T42Window","TrayMinimize",m_bTrayMinimize); | ||
965 | app->WriteProfileInt("T42Window","SleepMinimize",m_bSleepMinimize); | ||
966 | app->WriteProfileInt("T42Window","OnWake",m_onWake); | ||
967 | app->WriteProfileInt("T42Window","MinimizeSleep",m_bMinimizeSleep); | ||
968 | } | ||
969 | void T42Frame::LoadLayout() | ||
970 | { | ||
971 | CWinApp* app = AfxGetApp(); | ||
972 | m_bTrayMinimize = app->GetProfileInt("T42Window","TrayMinimize",m_bTrayMinimize); | ||
973 | m_bSleepMinimize = app->GetProfileInt("T42Window","SleepMinimize",m_bSleepMinimize); | ||
974 | m_onWake = app->GetProfileInt("T42Window","OnWake",m_onWake); | ||
975 | m_bMinimizeSleep = app->GetProfileInt("T42Window","MinimizeSleep",m_bMinimizeSleep); | ||
976 | } | ||
977 | |||
978 | void T42Frame::SetPeerName(LPCTSTR str) | ||
979 | { | ||
980 | T42Document* pDoc = (T42Document*)GetActiveDocument(); | ||
981 | ASSERT_KINDOF(T42Document,pDoc); | ||
982 | CString n = str?str:m_Target; | ||
983 | pDoc->SetTitle(n); | ||
984 | m_wndFake.SetWindowText("Talk with "+n); | ||
985 | } | ||
986 | |||
987 | void T42Frame::OnUpdateFrameTitle(BOOL bAddToTitle) | ||
988 | { | ||
989 | T42Document* pDoc = (T42Document*)GetActiveDocument(); | ||
990 | ASSERT_KINDOF(T42Document,pDoc); | ||
991 | CString title; | ||
992 | if(bAddToTitle && pDoc && m_bEstablished) | ||
993 | title.Format(IDS_TITLE_TEAWITH,pDoc->GetTitle()); | ||
994 | else | ||
995 | title.LoadString(IDS_TITLE_TEAFORTWO); | ||
996 | SetWindowText(title); | ||
997 | } | ||
998 | |||
999 | void T42Frame::AddToHotList(LPCTSTR str) | ||
1000 | { | ||
1001 | CT42App* app = (CT42App*)AfxGetApp(); | ||
1002 | app->LastCallee(str?str:m_Target); | ||
1003 | } | ||
1004 | |||
1005 | void T42Frame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) | ||
1006 | { | ||
1007 | CFrameWnd::OnActivate(nState, pWndOther, bMinimized); | ||
1008 | if(nState==WA_INACTIVE){ | ||
1009 | m_bHaveFocus=FALSE; | ||
1010 | }else{ | ||
1011 | DeTray(); | ||
1012 | SetTheIcon(m_hNormal); | ||
1013 | m_bHaveFocus=TRUE; | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | LRESULT T42Frame::OnTrayIcon(WPARAM wP,LPARAM lP) | ||
1018 | { | ||
1019 | ASSERT(wP==IDC_TRAYICON); | ||
1020 | if(lP==WM_LBUTTONDOWN) | ||
1021 | SetForegroundWindow(); | ||
1022 | return 0; | ||
1023 | } | ||
1024 | |||
1025 | void T42Frame::SetTheIcon(HICON hicon) | ||
1026 | { | ||
1027 | SetIcon(hicon,TRUE); SetIcon(hicon,FALSE); | ||
1028 | if(m_bTrayed){ | ||
1029 | NOTIFYICONDATA nid; | ||
1030 | memset(&nid,0,sizeof(nid)); | ||
1031 | nid.cbSize=sizeof(nid); | ||
1032 | nid.hWnd = m_hWnd; | ||
1033 | nid.uID = IDC_TRAYICON; | ||
1034 | nid.uFlags = NIF_ICON; | ||
1035 | nid.hIcon =hicon; | ||
1036 | VERIFY(Shell_NotifyIcon(NIM_MODIFY,&nid)); | ||
1037 | } | ||
1038 | } | ||
1039 | |||
1040 | void T42Frame::OnUpdateWindowHideintrayonminimize(CCmdUI* pCmdUI) | ||
1041 | { | ||
1042 | pCmdUI->SetCheck(m_bTrayMinimize?1:0); | ||
1043 | } | ||
1044 | void T42Frame::OnWindowHideintrayonminimize() | ||
1045 | { | ||
1046 | m_bTrayMinimize=!m_bTrayMinimize; | ||
1047 | } | ||
1048 | |||
1049 | void T42Frame::OnTalkAbort() | ||
1050 | { | ||
1051 | ASSERT(m_Socket); | ||
1052 | closesocket(m_Socket); | ||
1053 | StatusLine(IDS_STATUS_CONNECTIONCLOSED); | ||
1054 | SystemMessage(IDS_CONNECTIONCLOSED); | ||
1055 | Established(FALSE); | ||
1056 | } | ||
1057 | void T42Frame::OnUpdateTalkAbort(CCmdUI* pCmdUI) | ||
1058 | { | ||
1059 | pCmdUI->Enable(m_bEstablished); | ||
1060 | } | ||
1061 | void T42Frame::OnTalkReconnect() | ||
1062 | { | ||
1063 | PostMessage(WM_INITIATETALK); | ||
1064 | } | ||
1065 | void T42Frame::OnUpdateTalkReconnect(CCmdUI* pCmdUI) | ||
1066 | { | ||
1067 | pCmdUI->Enable((!m_bEstablished) && (!m_Target.IsEmpty())); | ||
1068 | } | ||
1069 | void T42Frame::OnUpdateTalkRemoteuser(CCmdUI* pCmdUI) | ||
1070 | { | ||
1071 | pCmdUI->Enable(!m_bEstablished); | ||
1072 | } | ||
1073 | |||
1074 | void T42Frame::WakeUp() | ||
1075 | { | ||
1076 | if(m_onWake&wakeSound){ | ||
1077 | CT42App* app = (CT42App*)AfxGetApp(); | ||
1078 | ASSERT(app); | ||
1079 | app->StartSound(app->m_sndT42Wake); | ||
1080 | } | ||
1081 | if(m_onWake&wakePopup) | ||
1082 | SetForegroundWindow(); | ||
1083 | m_bSleep=FALSE; | ||
1084 | } | ||
1085 | |||
1086 | void T42Frame::OnUpdateSleepSleep(CCmdUI* pCmdUI) | ||
1087 | { | ||
1088 | pCmdUI->SetCheck(m_bSleep?1:0); | ||
1089 | } | ||
1090 | void T42Frame::OnSleepSleep() | ||
1091 | { | ||
1092 | m_bSleep=!m_bSleep; | ||
1093 | if(m_bSleep && m_bMinimizeSleep) | ||
1094 | PostMessage(WM_SYSCOMMAND,SC_MINIMIZE); | ||
1095 | } | ||
1096 | |||
1097 | void T42Frame::OnUpdateSleepSleeponminimize(CCmdUI* pCmdUI) | ||
1098 | { | ||
1099 | pCmdUI->SetCheck(m_bSleepMinimize?1:0); | ||
1100 | } | ||
1101 | void T42Frame::OnSleepSleeponminimize() | ||
1102 | { | ||
1103 | m_bSleepMinimize=!m_bSleepMinimize; | ||
1104 | } | ||
1105 | |||
1106 | void T42Frame::OnUpdateSleepWakeupactionMakesound(CCmdUI* pCmdUI) | ||
1107 | { | ||
1108 | pCmdUI->SetCheck((m_onWake&wakeSound)?1:0); | ||
1109 | } | ||
1110 | void T42Frame::OnSleepWakeupactionMakesound() | ||
1111 | { | ||
1112 | m_onWake^=wakeSound; | ||
1113 | } | ||
1114 | |||
1115 | void T42Frame::OnUpdateSleepWakeupactionPopup(CCmdUI* pCmdUI) | ||
1116 | { | ||
1117 | pCmdUI->SetCheck((m_onWake&wakePopup)?1:0); | ||
1118 | } | ||
1119 | void T42Frame::OnSleepWakeupactionPopup() | ||
1120 | { | ||
1121 | m_onWake^=wakePopup; | ||
1122 | } | ||
1123 | |||
1124 | void T42Frame::DeTray() | ||
1125 | { | ||
1126 | if(!m_bTrayed) | ||
1127 | return; | ||
1128 | NOTIFYICONDATA nid; | ||
1129 | memset(&nid,0,sizeof(nid)); | ||
1130 | nid.cbSize=sizeof(nid); | ||
1131 | nid.hWnd = m_hWnd; | ||
1132 | nid.uID = IDC_TRAYICON; | ||
1133 | nid.uFlags = 0; | ||
1134 | VERIFY(Shell_NotifyIcon(NIM_DELETE,&nid)); | ||
1135 | m_bTrayed=FALSE; | ||
1136 | ShowWindow(SW_SHOW); | ||
1137 | } | ||
1138 | |||
1139 | void T42Frame::OnUpdateSleepMinimizeonsleep(CCmdUI* pCmdUI) | ||
1140 | { | ||
1141 | pCmdUI->SetCheck(m_bMinimizeSleep?1:0); | ||
1142 | } | ||
1143 | void T42Frame::OnSleepMinimizeonsleep() | ||
1144 | { | ||
1145 | m_bMinimizeSleep=!m_bMinimizeSleep; | ||
1146 | } | ||
1147 | |||
1148 | void T42Frame::OnTalkClose() | ||
1149 | { | ||
1150 | PostMessage(WM_CLOSE); | ||
1151 | } | ||
1152 | |||
1153 | void T42Frame::SystemMessage(UINT nID) | ||
1154 | { | ||
1155 | CString tmp; | ||
1156 | VERIFY(tmp.LoadString(nID)); | ||
1157 | SystemMessage(tmp); | ||
1158 | } | ||
1159 | |||
1160 | void T42Frame::SystemMessage(LPCTSTR str) | ||
1161 | { | ||
1162 | T42View* pView = (T42View*)GetActiveView(); | ||
1163 | ASSERT_KINDOF(T42View,pView); | ||
1164 | pView->SystemMessage(str); | ||
1165 | } | ||
1166 | |||
1167 | void T42Frame::SystemMessage(UINT nID,UINT nIDi) | ||
1168 | { | ||
1169 | CString idi; | ||
1170 | VERIFY(idi.LoadString(nIDi)); | ||
1171 | CString tmp; | ||
1172 | tmp.Format(nID,idi); | ||
1173 | SystemMessage(tmp); | ||
1174 | } | ||
1175 | |||
1176 | void T42Frame::WSSystemMessage(UINT nID,LONG wsaError) | ||
1177 | { | ||
1178 | UINT wsid = 0; | ||
1179 | switch(wsaError){ | ||
1180 | case WSAENETDOWN: wsid = IDS_WSA_ENETDOWN; break; | ||
1181 | case WSAECONNRESET: wsid = IDS_WSA_ECONNRESET; break; | ||
1182 | case WSAECONNABORTED: wsid = IDS_WSA_ECONNABORTED; break; | ||
1183 | case WSAECONNREFUSED: wsid = IDS_WSA_ECONNREFUSED; break; | ||
1184 | case WSAENETUNREACH: wsid = IDS_WSA_ENETUNREACH; break; | ||
1185 | case WSAETIMEDOUT: wsid = IDS_WSA_ETIMEDOUT; break; | ||
1186 | case WSAHOST_NOT_FOUND: wsid = IDS_WSA_HOSTNOTFOUND; break; | ||
1187 | case WSANO_DATA: wsid = IDS_WSA_NODATA; break; | ||
1188 | } | ||
1189 | if(wsid) | ||
1190 | SystemMessage(nID,wsid); | ||
1191 | else{ | ||
1192 | CString tmp; | ||
1193 | tmp.Format("#%ld",wsaError); | ||
1194 | SystemMessage(nID,tmp); | ||
1195 | } | ||
1196 | } | ||
1197 | |||
1198 | void T42Frame::SystemMessage(UINT nID,LPCTSTR str) | ||
1199 | { | ||
1200 | CString tmp; | ||
1201 | tmp.Format(nID,str); | ||
1202 | SystemMessage(tmp); | ||
1203 | } | ||
1204 | |||
1205 | void T42Frame::ActivateFrame(int nCmdShow) | ||
1206 | { | ||
1207 | T42Document* pDoc = (T42Document*)GetActiveDocument(); | ||
1208 | ASSERT_KINDOF(T42Document,pDoc); | ||
1209 | if(pDoc->m_bHidden) | ||
1210 | nCmdShow=SW_HIDE; | ||
1211 | CFrameWnd::ActivateFrame(nCmdShow); | ||
1212 | } | ||