summaryrefslogtreecommitdiffabout
path: root/T42Dlg.cpp
Unidiff
Diffstat (limited to 'T42Dlg.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--T42Dlg.cpp1251
1 files changed, 1251 insertions, 0 deletions
diff --git a/T42Dlg.cpp b/T42Dlg.cpp
new file mode 100644
index 0000000..8990957
--- a/dev/null
+++ b/T42Dlg.cpp
@@ -0,0 +1,1251 @@
1// T42Dlg.cpp : implementation file
2//
3
4#include "stdafx.h"
5#include "T42.h"
6#include "T42Dlg.h"
7
8#include "T42Frame.h"
9#include "T42AnnounceDlg.h"
10#include "T42Document.h"
11#include "T42Secretary.h"
12
13#ifdef _DEBUG
14#define new DEBUG_NEW
15#undef THIS_FILE
16static char THIS_FILE[] = __FILE__;
17#endif
18
19/////////////////////////////////////////////////////////////////////////////
20// CAboutDlg dialog used for App About
21
22class CAboutDlg : public CDialog
23{
24public:
25 CAboutDlg();
26
27// Dialog Data
28 //{{AFX_DATA(CAboutDlg)
29 enum { IDD = IDD_ABOUTBOX };
30 //}}AFX_DATA
31
32 // ClassWizard generated virtual function overrides
33 //{{AFX_VIRTUAL(CAboutDlg)
34 protected:
35 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
36 //}}AFX_VIRTUAL
37
38// Implementation
39protected:
40 //{{AFX_MSG(CAboutDlg)
41 afx_msg void OnKlevernet();
42 //}}AFX_MSG
43 DECLARE_MESSAGE_MAP()
44};
45
46CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
47{
48 //{{AFX_DATA_INIT(CAboutDlg)
49 //}}AFX_DATA_INIT
50}
51
52void CAboutDlg::DoDataExchange(CDataExchange* pDX)
53{
54 CDialog::DoDataExchange(pDX);
55 //{{AFX_DATA_MAP(CAboutDlg)
56 //}}AFX_DATA_MAP
57}
58
59BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
60 //{{AFX_MSG_MAP(CAboutDlg)
61 ON_BN_CLICKED(IDC_KLEVERNET, OnKlevernet)
62 //}}AFX_MSG_MAP
63END_MESSAGE_MAP()
64
65
66void CAboutDlg::OnKlevernet()
67{
68CString url;
69 VERIFY(url.LoadString(IDS_KLEVERNET_URL));
70 ShellExecute(::GetDesktopWindow(),"open",url,NULL,NULL,SW_SHOWMAXIMIZED);
71}
72
73/////////////////////////////////////////////////////////////////////////////
74// CT42Dlg dialog
75
76CT42Dlg::CT42Dlg(CWnd* pParent /*=NULL*/)
77 : CDialog(CT42Dlg::IDD, pParent),
78 m_sizeMin(0,0)
79{
80 //{{AFX_DATA_INIT(CT42Dlg)
81 //}}AFX_DATA_INIT
82 // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
83 m_hIconEmpty = m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
84 m_hIconFull = AfxGetApp()->LoadIcon(IDI_FULLCUP);
85 m_newCalls = 0;
86 m_daemonSocket = INVALID_SOCKET;
87 m_talkLifetime = CTimeSpan(0,0,3,0);// 3 mins..
88 m_trackTalkID = 1;
89 m_bmpBack.LoadBitmap(IDB_BACK);
90 m_bmpBack.GetBitmap(&m_bitmapBack);
91 m_bExiting = m_bShown = FALSE;
92 m_hExFW = NULL;
93 m_marginX = m_marginY = m_gapY = 0;
94 m_bAway = FALSE;
95 m_onCall = 0;
96 m_onCallAway = IDC_SECRETARY;
97 LoadSettings();
98}
99
100CT42Dlg::~CT42Dlg()
101{
102 SaveSettings();
103}
104
105void CT42Dlg::DoDataExchange(CDataExchange* pDX)
106{
107 CDialog::DoDataExchange(pDX);
108 //{{AFX_DATA_MAP(CT42Dlg)
109 DDX_Control(pDX, IDOK, m_ExitCtl);
110 DDX_Control(pDX, IDC_TALK, m_TeaCtl);
111 DDX_Control(pDX, IDC_AWAY, m_AwayCtl);
112 DDX_Control(pDX, ID_HELP, m_HelpCtl);
113 DDX_Control(pDX, IDC_OPTIONS, m_OptionsCtl);
114 DDX_Control(pDX, IDC_ONCALLAWAY, m_OnCallAwayCtl);
115 DDX_Control(pDX, IDC_ONCALL, m_OnCallCtl);
116 DDX_Control(pDX, IDC_CALLS, m_CallsCtl);
117 DDX_Control(pDX, IDC_PREVIEW, m_PreviewCtl);
118 //}}AFX_DATA_MAP
119 if(pDX->m_bSaveAndValidate){
120 m_onCall = GetOnCtl(m_OnCallCtl);
121 m_onCallAway = GetOnCtl(m_OnCallAwayCtl);
122 }else{
123 SetOnCtl(m_onCall,m_OnCallCtl);
124 SetOnCtl(m_onCallAway,m_OnCallAwayCtl);
125 }
126}
127
128BEGIN_MESSAGE_MAP(CT42Dlg, CDialog)
129 //{{AFX_MSG_MAP(CT42Dlg)
130 ON_WM_SYSCOMMAND()
131 ON_WM_DESTROY()
132 ON_WM_PAINT()
133 ON_WM_QUERYDRAGICON()
134 ON_BN_CLICKED(IDC_TALK, OnTalk)
135 ON_MESSAGE(WM_DAEMON, OnDaemon)
136 ON_WM_CREATE()
137 ON_MESSAGE(WM_TRAYICON, OnTrayIcon)
138 ON_WM_WINDOWPOSCHANGING()
139 ON_COMMAND(ID_TRAY_EXIT, OnTrayExit)
140 ON_COMMAND(ID_TRAY_OPTIONS, OnTrayOptions)
141 ON_COMMAND(ID_TRAY_SHOWMAINWINDOW, OnTrayShowmainwindow)
142 ON_COMMAND(ID_TRAY_T42, OnTrayT42)
143 ON_BN_CLICKED(IDC_OPTIONS, OnOptions)
144 ON_NOTIFY(LVN_GETDISPINFO, IDC_CALLS, OnGetdispinfoCalls)
145 ON_NOTIFY(LVN_ITEMCHANGED, IDC_CALLS, OnItemchangedCalls)
146 ON_NOTIFY(NM_RCLICK, IDC_CALLS, OnRclickCalls)
147 ON_COMMAND(ID_CALLLOG_CALLBACK, OnCalllogCallback)
148 ON_COMMAND(ID_CALLLOG_DELETE, OnCalllogDelete)
149 ON_COMMAND(ID_CALLLOG_SAVETOFILE, OnCalllogSavetofile)
150 ON_COMMAND(ID_CALLLOG_EMPTYLOG, OnCalllogEmptylog)
151 ON_NOTIFY(LVN_DELETEITEM, IDC_CALLS, OnDeleteitemCalls)
152 ON_MESSAGE(WM_UPDATEPREVIEW, OnUpdatePreview)
153 ON_NOTIFY(LVN_KEYDOWN, IDC_CALLS, OnKeydownCalls)
154 ON_WM_SHOWWINDOW()
155 ON_COMMAND(ID_CALLLOG_MARKASNEW, OnCalllogMarkasnew)
156 ON_COMMAND(ID_CALLLOG_MARKASPROCESSED, OnCalllogMarkasprocessed)
157 ON_WM_SIZE()
158 ON_WM_GETMINMAXINFO()
159 ON_BN_CLICKED(IDC_AWAY, OnAway)
160 ON_CBN_SELENDOK(IDC_ONCALL, OnSelendokOncall)
161 ON_CBN_SELENDOK(IDC_ONCALLAWAY, OnSelendokOncallaway)
162 ON_COMMAND(ID_TRAY_AWAY, OnTrayAway)
163 ON_WM_TIMER()
164 ON_WM_QUERYENDSESSION()
165 //}}AFX_MSG_MAP
166END_MESSAGE_MAP()
167
168/////////////////////////////////////////////////////////////////////////////
169// CT42Dlg message handlers
170
171BOOL CT42Dlg::OnInitDialog()
172{
173 CDialog::OnInitDialog();
174
175 // Add "About..." menu item to system menu.
176
177 // IDM_ABOUTBOX must be in the system command range.
178 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
179 ASSERT(IDM_ABOUTBOX < 0xF000);
180
181 CMenu* pSysMenu = GetSystemMenu(FALSE);
182 CString strAboutMenu;
183 strAboutMenu.LoadString(IDS_ABOUTBOX);
184 if (!strAboutMenu.IsEmpty())
185 {
186 pSysMenu->AppendMenu(MF_SEPARATOR);
187 pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
188 }
189
190 // Set the icon for this dialog. The framework does this automatically
191 // when the application's main window is not a dialog
192 SetIcon(m_hIcon, TRUE); // Set big icon
193 SetIcon(m_hIcon, FALSE); // Set small icon
194
195CT42App* app = (CT42App*)AfxGetApp();
196{
197int x = -1,y = -1,cx = -1,cy = -1;
198 x = app->GetProfileInt("T42MainWindow","X",x);
199 y = app->GetProfileInt("T42MainWindow","Y",y);
200 cx = app->GetProfileInt("T42MainWindow","Width",cx);
201 cy = app->GetProfileInt("T42MainWindow","Height",cy);
202 if(cx>0 && cy>0)
203 SetWindowPos(NULL,x,y,cx,cy,SWP_NOACTIVATE|SWP_NOZORDER);
204}
205
206 ::SetForegroundWindow(m_hExFW);
207
208 m_PreviewCtl.ModifyStyle(0,WS_VSCROLL);
209 m_PreviewCtl.SetOptions(ECOOP_SET,ECO_AUTOWORDSELECTION|
210 ECO_AUTOVSCROLL|ECO_AUTOHSCROLL|ECO_READONLY|ECO_SELECTIONBAR);
211 m_PreviewCtl.SetReadOnly(TRUE);
212 m_PreviewCtl.SetTargetDevice(NULL,0);
213 m_PreviewCtl.SetBackgroundColor(FALSE,((CT42App*)AfxGetApp())->m_crT42RemoteBG);
214
215 m_CallsCtl.SetBkColor(RGB(0,192,0));
216 m_CallsCtl.SetTextColor(RGB(255,255,0));
217 m_CallsCtl.SetTextBkColor(RGB(0,192,0));
218 m_Images.Create(16,16,TRUE,2,1);
219 m_iNew = m_Images.Add(AfxGetApp()->LoadIcon(IDI_T42CALLNEW));
220 m_iProcessed = m_Images.Add(AfxGetApp()->LoadIcon(IDI_T42CALLPROCESSED));
221 ASSERT( m_iNew>=0 && m_iProcessed>=0);
222 m_CallsCtl.SetImageList(&m_Images,LVSIL_NORMAL);
223 m_CallsCtl.SetImageList(&m_Images,LVSIL_SMALL);
224 m_CallsCtl.SetImageList(&m_Images,LVSIL_STATE);
225 InitCalls();
226
227CRect wrci, wrco;
228 GetWindowRect(&wrco);
229 GetClientRect(&wrci);
230 // Pull out margins
231CRect crc;
232 m_CallsCtl.GetWindowRect(crc); ScreenToClient(crc);
233 m_marginX = crc.left;
234CRect trc;
235 m_TeaCtl.GetWindowRect(trc); ScreenToClient(trc);
236 m_marginY = trc.top;
237CRect prc;
238 m_PreviewCtl.GetWindowRect(prc); ScreenToClient(prc);
239 m_gapY = prc.top-crc.bottom;
240
241 RecalcLayout();
242 SetColumnWidths();
243
244 // Calc minimum size
245CRect arc;
246 m_AwayCtl.GetWindowRect(arc); ScreenToClient(arc);
247 m_sizeMin.cx = arc.right+m_marginX*2+trc.Width()+wrco.Width()-wrci.Width();
248 m_sizeMin.cy = crc.top+m_marginY+m_gapY+40*2+wrco.Height()-wrci.Height();
249
250 SetTimer(timerMinutes,60000,NULL);
251
252 m_daemonSocket = socket(AF_INET,SOCK_DGRAM,0);
253 if(m_daemonSocket == INVALID_SOCKET){
254 TRACE0("Failed to initialize daemon\n");
255 return TRUE;
256 }
257sockaddr_in da;
258 da.sin_family = AF_INET;
259 da.sin_port = htons(app->m_T42TalkPort);
260 da.sin_addr.s_addr = INADDR_ANY;
261 if(bind(m_daemonSocket,(sockaddr*)&da,sizeof(da))){
262 AfxMessageBox(IDS_DAEMON_FAIL,MB_OK|MB_ICONSTOP);
263 TRACE0("Failed to bind daemon socket\n");
264 return TRUE;
265 }
266 if(WSAAsyncSelect(m_daemonSocket,m_hWnd,WM_DAEMON,FD_READ)){
267 AfxMessageBox(IDS_DAEMON_FAIL,MB_OK|MB_ICONSTOP);
268 TRACE0("AsyncSelect failed on daemon socket\n");
269 return TRUE;
270 }
271
272 return TRUE; // return TRUE unless you set the focus to a control
273}
274
275void CT42Dlg::OnSysCommand(UINT nID, LPARAM lParam)
276{
277 if ((nID & 0xFFF0) == IDM_ABOUTBOX){
278 CAboutDlg dlgAbout;
279 dlgAbout.DoModal();
280 }else{
281 if(nID==SC_SCREENSAVE){
282 TRACE0("SCRS\n");
283 }else if(nID==SC_MONITORPOWER){
284 TRACE0("MP\n");
285 }else
286 TRACE1("SYSCOM: 0x%04X\n",nID);
287 CDialog::OnSysCommand(nID, lParam);
288 }
289}
290
291void CT42Dlg::OnDestroy()
292{
293CT42App* app = (CT42App*)AfxGetApp();
294CDocTemplate* pTemplate = app->m_pTemplate;
295 pTemplate->CloseAllDocuments(FALSE);
296CRect rc;
297 GetWindowRect(rc);
298 app->WriteProfileInt("T42MainWindow","X",rc.left);
299 app->WriteProfileInt("T42MainWindow","Y",rc.top);
300 app->WriteProfileInt("T42MainWindow","Width",rc.Width());
301 app->WriteProfileInt("T42MainWindow","Height",rc.Height());
302
303NOTIFYICONDATA nid;
304 memset(&nid,0,sizeof(nid));
305 nid.cbSize=sizeof(nid);
306 nid.hWnd=m_hWnd;
307 nid.uID=IDC_TRAYICON;
308 nid.uFlags=0;
309 VERIFY(Shell_NotifyIcon(NIM_DELETE,&nid));
310
311 WinHelp(0L, HELP_QUIT);
312 CDialog::OnDestroy();
313}
314
315// If you add a minimize button to your dialog, you will need the code below
316// to draw the icon. For MFC applications using the document/view model,
317// this is automatically done for you by the framework.
318
319void CT42Dlg::OnPaint()
320{
321 if (IsIconic())
322 {
323 CPaintDC dc(this); // device context for painting
324
325 SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
326
327 // Center icon in client rectangle
328 int cxIcon = GetSystemMetrics(SM_CXICON);
329 int cyIcon = GetSystemMetrics(SM_CYICON);
330 CRect rect;
331 GetClientRect(&rect);
332 int x = (rect.Width() - cxIcon + 1) / 2;
333 int y = (rect.Height() - cyIcon + 1) / 2;
334
335 // Draw the icon
336 dc.DrawIcon(x, y, m_hIcon);
337 }
338 else
339 {
340 CPaintDC pDC(this);
341 CDC bmpDC;
342 bmpDC.CreateCompatibleDC(&pDC);
343 bmpDC.SelectObject(&m_bmpBack);
344 CRect rc;
345 GetClientRect(&rc);
346 for(int x=-m_bitmapBack.bmWidth*2/4;x<rc.Width();x+=m_bitmapBack.bmWidth)
347 for(int y=-m_bitmapBack.bmHeight*2/4;y<rc.Height();y+=m_bitmapBack.bmHeight)
348 pDC.BitBlt(x,y,m_bitmapBack.bmWidth,m_bitmapBack.bmHeight,&bmpDC,0,0,SRCCOPY);
349 bmpDC.DeleteDC();
350 CDialog::OnPaint();
351 }
352}
353
354// The system calls this to obtain the cursor to display while the user drags
355// the minimized window.
356HCURSOR CT42Dlg::OnQueryDragIcon()
357{
358 return (HCURSOR) m_hIcon;
359}
360
361void CT42Dlg::OnTalk()
362{
363CDocTemplate* pTemplate = ((CT42App*)AfxGetApp())->m_pTemplate;
364T42Document* pDoc = (T42Document*)pTemplate->OpenDocumentFile(NULL);
365 ASSERT_KINDOF(T42Document,pDoc);
366 pDoc->Talk();
367}
368
369LRESULT CT42Dlg::OnDaemon(WPARAM wP,LPARAM lP)
370{
371 if(WSAGETSELECTERROR(lP)){
372 TRACE1("Error on daemon socket: %ld\n", WSAGETSELECTERROR(lP));
373 return -1;
374 }
375 ASSERT(WSAGETSELECTEVENT(lP)&FD_READ);
376TalkCtlMessage rq;
377 if(recv(m_daemonSocket,(char*)&rq,sizeof(rq),0)!=sizeof(rq)){
378 TRACE("Bad packet size on daemon socket\n");
379 return -1;
380 }
381TalkCtlResponse rp;
382 TRACE3("*DAEMON-REQUEST*\nV: %d, T: %d, ID: %ld\n",
383 (int)rq.m_Version, (int)rq.m_Type, ntohl(rq.m_ID)
384 );
385 TRACE2("ADDR: %s:%d\n",
386 inet_ntoa(((sockaddr_in*)&rq.m_Addr)->sin_addr),
387 ntohs(((sockaddr_in*)&rq.m_Addr)->sin_port)
388 );
389 TRACE2("CTL ADDR: %s:%d\n",
390 inet_ntoa(((sockaddr_in*)&rq.m_ctlAddr)->sin_addr),
391 ntohs(((sockaddr_in*)&rq.m_ctlAddr)->sin_port)
392 );
393 TRACE3("PID: %ld, LU: %s, RU: %s\n",
394 rq.m_PID,rq.m_LName,rq.m_RName
395 );
396 TRACE1("TTY: %s\n---\n",rq.m_RTTY);
397
398 rp.m_Version = talkCtlVersion;
399 rp.m_Type = rq.m_Type;
400 rp.m_ID = htonl(0);
401 rp.m_Answer = talkCtlReserved;
402sockaddr_in a;
403 memmove(&a,&rq.m_ctlAddr,sizeof(a));
404 a.sin_family = ntohs(a.sin_family);
405 do{
406 if(rq.m_Version!=talkCtlVersion){
407 rp.m_Answer = talkCtlBadVersion;
408 break;
409 }
410 if(rq.m_Addr.sa_family!=htons(AF_INET)){
411 rp.m_Answer = talkCtlBadAddr;
412 break;
413 }
414 if(rq.m_ctlAddr.sa_family!=htons(AF_INET)){
415 rp.m_Answer = talkCtlBadCtlAddr;
416 break;
417 }
418 switch(rq.m_Type){
419 case talkCtlReqAnnounce:
420 {
421 CTime ct = CTime::GetCurrentTime();
422 POSITION p = m_talks.GetHeadPosition();
423 BOOL bFound = FALSE;
424 while(p){
425 POSITION dp = p;
426 CTTable& t = m_talks.GetNext(p);
427 if((ct-t.m_Time)>m_talkLifetime){
428 TRACE0("Removing Expired request\n");
429 m_talks.RemoveAt(dp);
430 }else if(t==rq){
431 t.m_Time = ct;
432 rp.m_ID = t.m_RQ.m_ID;
433 bFound = TRUE;
434 break;
435 }
436 }
437 if(bFound){
438 // ** handle re-announces
439 rp.m_Answer = talkCtlSuccess;
440 break;
441 }
442 UINT nAction = m_bAway?m_onCallAway:m_onCall;
443 T42AnnounceDlg ad(rq);
444 CT42App* app = (CT42App*)AfxGetApp();
445 if(
446 nAction==IDC_SECRETARY
447 && app->m_T42SWinLimit
448 && app->m_T42LinesBusy>=app->m_T42SWinLimit
449 )
450 nAction = IDC_NOTHERE;// ??
451 if(nAction!=IDC_SECRETARY && nAction!=IDC_NOTHERE
452 && nAction!=IDC_REFUSE && nAction!=IDCANCEL
453 ){
454 CTTable t;
455 memmove(&t.m_RQ,&rq,sizeof(t.m_RQ));
456 t.m_Time = ct;
457 t.m_RQ.m_ID = rp.m_ID = htonl(m_trackTalkID++);
458 m_talks.AddHead(t);
459 rp.m_Answer = talkCtlSuccess;
460 if(sendto(m_daemonSocket,(char*)&rp,sizeof(rp),0,(sockaddr*)&a,sizeof(a))!=sizeof(rp)){
461 TRACE0("Failed to send daemon response\n");
462 return -1;
463 }
464 HWND hFW = ::GetForegroundWindow();
465 nAction = ad.DoModal();
466 ::SetForegroundWindow(hFW);
467 }else{
468 if(nAction==IDC_NOTHERE || nAction==IDC_REFUSE){
469 rp.m_Answer=(nAction==IDC_NOTHERE)?talkCtlNotHere:talkCtlPermissionDenied;
470 break;
471 }
472 CTTable t;
473 memmove(&t.m_RQ,&rq,sizeof(t.m_RQ));
474 t.m_Time = ct;
475 t.m_RQ.m_ID = rp.m_ID = htonl(m_trackTalkID++);
476 m_talks.AddHead(t);
477 rp.m_Answer = talkCtlSuccess;
478 if(sendto(m_daemonSocket,(char*)&rp,sizeof(rp),0,(sockaddr*)&a,sizeof(a))!=sizeof(rp)){
479 TRACE0("Failed to send daemon response\n");
480 return -1;
481 }
482 }
483 rp.m_Answer=talkCtlReserved;
484 switch(nAction){
485 case IDOK:
486 {
487 CDocTemplate* pTemplate = ((CT42App*)AfxGetApp())->m_pTemplate;
488 T42Document* pDoc = (T42Document*)pTemplate->OpenDocumentFile(NULL);
489 ASSERT_KINDOF(T42Document,pDoc);
490 pDoc->Talk(ad.m_Callee,ad.m_ipCaller,NULL);
491 }
492 break;
493 case IDC_SECRETARY:
494 {
495 HWND hFW = ::GetForegroundWindow();
496 CDocTemplate* pTemplate = ((CT42App*)AfxGetApp())->m_pTemplate;
497 T42Document* pDoc = (T42Document*)pTemplate->OpenDocumentFile("hidden");
498 ASSERT_KINDOF(T42Document,pDoc);
499 pDoc->AttachRobot(new CT42Secretary);
500 pDoc->Talk(ad.m_Callee,ad.m_ipCaller,NULL);
501 ::SetForegroundWindow(hFW);
502 }
503 break;
504 case IDCANCEL:
505 break;
506 }
507 }
508 break;
509 case talkCtlReqLeaveInvite:
510 {
511 CTime ct = CTime::GetCurrentTime();
512 POSITION p = m_talks.GetHeadPosition();
513 while(p){
514 POSITION dp = p;
515 CTTable& t = m_talks.GetNext(p);
516 if((ct-t.m_Time)>m_talkLifetime){
517 TRACE0("Removing Expired request\n");
518 m_talks.RemoveAt(dp);
519 }else if(t==rq){
520 t.m_Time = ct;
521 rp.m_ID = rq.m_ID;
522 rp.m_Answer = talkCtlSuccess;
523 break;
524 }
525 }
526 if(rp.m_Answer!=talkCtlSuccess){
527 CTTable t;
528 memmove(&t.m_RQ,&rq,sizeof(t.m_RQ));
529 t.m_Time = ct;
530 t.m_RQ.m_ID = rp.m_ID = htonl(m_trackTalkID++);
531 m_talks.AddHead(t);
532 rp.m_Answer = talkCtlSuccess;
533 }
534 }
535 break;
536 case talkCtlReqLookUp:
537 {
538 CTime ct = CTime::GetCurrentTime();
539 POSITION p = m_talks.GetHeadPosition();
540 while(p){
541 POSITION dp = p;
542 CTTable& t = m_talks.GetNext(p);
543 if((ct-t.m_Time)>m_talkLifetime){
544 TRACE0("Removing Expired request\n");
545 m_talks.RemoveAt(dp);
546 }else if(t.Match(rq)){
547 rp.m_ID = t.m_RQ.m_ID;
548 memmove(&rp.m_Addr,&t.m_RQ.m_Addr,sizeof(rp.m_Addr));
549 rp.m_Answer = talkCtlSuccess;
550 break;
551 }
552 }
553 if(rp.m_Answer!=talkCtlSuccess)
554 rp.m_Answer = talkCtlNotHere;
555 }
556 break;
557 case talkCtlReqDelete:
558 {
559 CTime ct = CTime::GetCurrentTime();
560 POSITION p = m_talks.GetHeadPosition();
561 while(p){
562 POSITION dp = p;
563 CTTable& t = m_talks.GetNext(p);
564 if((ct-t.m_Time)>m_talkLifetime){
565 TRACE0("Removing Expired request\n");
566 m_talks.RemoveAt(dp);
567 }else if(t.m_RQ.m_ID == rq.m_ID){
568 m_talks.RemoveAt(dp);
569 rp.m_Answer=talkCtlSuccess;
570 break;
571 }
572 }
573 if(rp.m_Answer!=talkCtlSuccess)
574 rp.m_Answer = talkCtlNotHere;
575 break;
576 }
577 break;
578 default:
579 TRACE0("Unknown request type\n");
580 rp.m_Answer=talkCtlUnknownRequest;
581 break;
582 }
583 }while(FALSE);
584 if(rp.m_Answer==talkCtlReserved || rp.m_Answer==talkCtlBadCtlAddr)
585 return -1;
586 if(sendto(m_daemonSocket,(char*)&rp,sizeof(rp),0,(sockaddr*)&a,sizeof(a))!=sizeof(rp)){
587 TRACE0("Failed to send daemon response\n");
588 return -1;
589 }
590 return 0;
591}
592
593int CT42Dlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
594{
595 if (CDialog::OnCreate(lpCreateStruct) == -1)
596 return -1;
597CRichEditCtrl tmp;
598 tmp.Create(WS_CHILD,CRect(0,0,0,0),this,0);
599
600NOTIFYICONDATA nid;
601 memset(&nid,0,sizeof(nid));
602 nid.cbSize = sizeof(nid);
603 nid.hWnd = m_hWnd;
604 nid.uID = IDC_TRAYICON;
605 nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
606 nid.uCallbackMessage=WM_TRAYICON;
607 nid.hIcon = m_hIcon;
608 // ***
609 strcpy(nid.szTip,"Tea For Two");
610 VERIFY(Shell_NotifyIcon(NIM_ADD,&nid));
611
612 return 0;
613}
614
615LRESULT CT42Dlg::OnTrayIcon(WPARAM wP,LPARAM lP)
616{
617 ASSERT(wP==IDC_TRAYICON);
618 switch(lP){
619 case WM_LBUTTONDOWN:
620 ToggleVisibility();
621 break;
622 case WM_RBUTTONDOWN:
623 {
624 CMenu popups;
625 VERIFY(popups.LoadMenu(IDM_POPUPS));
626 CMenu* popUp = popups.GetSubMenu(0);
627 ASSERT(popUp);
628 CPoint pt;
629 VERIFY(::GetCursorPos(&pt));
630 SetForegroundWindow();
631 popUp->CheckMenuItem(ID_TRAY_SHOWMAINWINDOW,MF_BYCOMMAND|(IsWindowVisible()?MF_CHECKED:MF_UNCHECKED));
632 popUp->CheckMenuItem(ID_TRAY_AWAY,MF_BYCOMMAND|(m_bAway?MF_CHECKED:MF_UNCHECKED));
633 popUp->TrackPopupMenu(TPM_RIGHTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
634 pt.x,pt.y,this);
635 SendMessage(WM_NULL);
636 }
637 break;
638 }
639 return 0;
640}
641
642void CT42Dlg::ToggleVisibility()
643{
644 if(IsWindowVisible()){
645 m_bShown=FALSE;
646 ShowWindow(SW_HIDE);
647 CWnd* pWnd = GetNextWindow();
648 if(pWnd){
649 pWnd->SetForegroundWindow();
650 pWnd->SetFocus();
651 }
652 }else{
653 m_bShown=TRUE;
654 ShowWindow(SW_SHOW);
655 SetForegroundWindow();
656 SetFocus();
657 }
658}
659
660void CT42Dlg::OnCancel()
661{
662 ToggleVisibility();
663}
664
665
666void CT42Dlg::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
667{
668 CDialog::OnWindowPosChanging(lpwndpos);
669
670 if(m_bExiting)
671 return;
672 if(m_bShown){
673 lpwndpos->flags&=~SWP_HIDEWINDOW;
674 lpwndpos->flags|=SWP_SHOWWINDOW;
675 }else{
676 lpwndpos->flags&=~SWP_SHOWWINDOW;
677 lpwndpos->flags|=SWP_HIDEWINDOW;
678 }
679}
680
681void CT42Dlg::OnOK()
682{
683 m_bExiting = TRUE;
684 CDialog::OnOK();
685}
686
687void CT42Dlg::OnTrayExit()
688{
689 OnOK();
690}
691
692void CT42Dlg::OnTrayOptions()
693{
694 OnOptions();
695}
696
697void CT42Dlg::OnTrayShowmainwindow()
698{
699 ToggleVisibility();
700}
701
702void CT42Dlg::OnTrayT42()
703{
704 OnTalk();
705}
706
707void CT42Dlg::OnOptions()
708{
709CT42App* app = (CT42App*)AfxGetApp();
710 app->Options(this);
711}
712
713void CT42Dlg::InitCalls()
714{
715CT42App* app = (CT42App*)AfxGetApp();
716 m_CallsCtl.InsertColumn(0,"Time",LVCFMT_LEFT,-1,subitemTime);
717 m_CallsCtl.InsertColumn(1,"Caller",LVCFMT_LEFT,-1,subitemCaller);
718 m_CallsCtl.InsertColumn(2,"Callee",LVCFMT_LEFT,-1,subitemCallee);
719LONG calls = app->GetT42Calls();
720 if(calls>0){
721 m_CallsCtl.SetItemCount(calls);
722 for(LONG tmp=0;tmp<calls;tmp++){
723 m_CallsCtl.InsertItem(
724 LVIF_TEXT,
725 tmp,
726 LPSTR_TEXTCALLBACK,
727 0,0,// state,statemask
728 I_IMAGECALLBACK,
729 0 // lParam
730 );
731 }
732 }
733 SetColumnWidths();
734}
735
736void CT42Dlg::OnGetdispinfoCalls(NMHDR* pNMHDR, LRESULT* pResult)
737{
738CT42App* app = (CT42App*)AfxGetApp();
739 LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
740int iItem = pDispInfo->item.iItem;
741CT42CallLogEntry entry;
742 VERIFY(app->GetT42Call(iItem,entry));
743CString tmp;
744 switch(pDispInfo->item.iSubItem){
745 case subitemTime:
746 tmp = entry.m_Time.Format(IDS_FORMAT_CALLTIME);
747 if(entry.m_Status==CT42CallLogEntry::statusProcessed)
748 pDispInfo->item.iImage = m_iProcessed;
749 else
750 pDispInfo->item.iImage = m_iNew;
751 break;
752 case subitemCaller:
753 tmp = entry.m_Caller;
754 break;
755 case subitemCallee:
756 tmp = entry.m_Callee;
757 break;
758 default:
759 ASSERT(FALSE);
760 break;
761 }
762 if(tmp.GetLength()>=pDispInfo->item.cchTextMax)
763 tmp = tmp.Left(pDispInfo->item.cchTextMax-4)+"..";
764 strcpy(pDispInfo->item.pszText,tmp);
765 pDispInfo->item.mask|=LVIF_IMAGE;
766 pDispInfo->item.mask|=LVIF_TEXT;
767
768 *pResult = 0;
769}
770
771void CT42Dlg::OnAddT42Call()
772{
773 m_CallsCtl.InsertItem(
774 LVIF_TEXT,
775 m_CallsCtl.GetItemCount(),
776 LPSTR_TEXTCALLBACK,
777 0,0,// state,statemask
778 I_IMAGECALLBACK,
779 0 // lParam
780 );
781 m_CallsCtl.RedrawItems(0,m_CallsCtl.GetItemCount());
782 m_CallsCtl.Invalidate();
783 PostMessage(WM_UPDATEPREVIEW,(WPARAM)-1);
784 if(!IsWindowVisible()){
785 m_newCalls++;
786 SetTheIcon(m_hIconFull);
787 }
788}
789
790void CT42Dlg::OnDelT42Call()
791{
792 m_CallsCtl.DeleteItem(
793 m_CallsCtl.GetItemCount()-1
794 );
795 m_CallsCtl.RedrawItems(0,m_CallsCtl.GetItemCount());
796 m_CallsCtl.Invalidate();
797 PostMessage(WM_UPDATEPREVIEW,(WPARAM)-1);
798}
799
800void CT42Dlg::SetColumnWidths()
801{
802CTime ct = CTime::GetCurrentTime();
803CString t = ct.Format(IDS_FORMAT_CALLTIME);
804CRect rc;
805 m_CallsCtl.GetClientRect(rc);
806INT tw = m_CallsCtl.GetStringWidth(t)+40;
807INT cew = m_CallsCtl.GetStringWidth("wwwwwwww");
808INT crw = rc.Width()-(tw+cew);
809 m_CallsCtl.SetColumnWidth(subitemTime,tw);
810 m_CallsCtl.SetColumnWidth(subitemCaller,crw);
811 m_CallsCtl.SetColumnWidth(subitemCallee,cew);
812}
813
814void CT42Dlg::OnItemchangedCalls(NMHDR* pNMHDR, LRESULT* pResult)
815{
816 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
817
818 if(
819 pNMListView->uChanged&LVIF_STATE
820 && pNMListView->uNewState&LVIS_FOCUSED
821 && !(pNMListView->uOldState&LVIS_FOCUSED)
822 ){
823 PostMessage(WM_UPDATEPREVIEW,pNMListView->iItem);
824 }
825 *pResult = 0;
826}
827
828DWORD CALLBACK CT42Dlg::ESOUTProc(DWORD dwCookie,LPBYTE pbBuff,LONG cb,LONG FAR *pcb)
829{
830CString* str = (CString*)dwCookie;
831 if(cb>str->GetLength())
832 cb = str->GetLength();
833 if(!cb){
834 (*pcb)=0;
835 return 0;
836 }
837 memmove(pbBuff,(LPCTSTR)*str,cb);
838 (*str) = str->Mid(cb);
839 (*pcb)=cb;
840 return 0;
841}
842
843void CT42Dlg::OnRclickCalls(NMHDR* pNMHDR, LRESULT* pResult)
844{
845CPoint pt;
846 VERIFY(GetCursorPos(&pt));
847CMenu popups;
848 VERIFY(popups.LoadMenu(IDM_POPUPS));
849CMenu* popup = popups.GetSubMenu(1);
850 ASSERT(popup);
851BOOL bYes = (
852 m_CallsCtl.GetNextItem(-1,LVNI_ALL|LVNI_FOCUSED)>=0
853 || m_CallsCtl.GetNextItem(-1,LVNI_ALL|LVNI_SELECTED)>=0
854 );
855 popup->EnableMenuItem(ID_CALLLOG_CALLBACK,MF_BYCOMMAND|(
856 bYes?MF_ENABLED:MF_GRAYED
857 ));
858 popup->EnableMenuItem(ID_CALLLOG_DELETE,MF_BYCOMMAND|(
859 bYes?MF_ENABLED:MF_GRAYED
860 ));
861 popup->EnableMenuItem(ID_CALLLOG_SAVETOFILE,MF_BYCOMMAND|(
862 bYes?MF_ENABLED:MF_GRAYED
863 ));
864 popup->EnableMenuItem(ID_CALLLOG_MARKASNEW,MF_BYCOMMAND|(
865 bYes?MF_ENABLED:MF_GRAYED
866 ));
867 popup->EnableMenuItem(ID_CALLLOG_MARKASPROCESSED,MF_BYCOMMAND|(
868 bYes?MF_ENABLED:MF_GRAYED
869 ));
870 popup->EnableMenuItem(ID_CALLLOG_EMPTYLOG,MF_BYCOMMAND|(
871 (m_CallsCtl.GetItemCount())?MF_ENABLED:MF_GRAYED
872 ));
873 popup->TrackPopupMenu(TPM_LEFTALIGN|TPM_RIGHTBUTTON|TPM_LEFTBUTTON,
874 pt.x,pt.y,this);
875 *pResult = 0;
876}
877
878void CT42Dlg::OnCalllogCallback()
879{
880int item = m_CallsCtl.GetNextItem(-1,LVNI_ALL|LVNI_FOCUSED);
881 if(item<0)
882 return;
883CT42App* app = (CT42App*)AfxGetApp();
884CT42CallLogEntry entry;
885 VERIFY(app->GetT42Call(item,entry));
886CDocTemplate* pTemplate = app->m_pTemplate;
887T42Document* pDoc = (T42Document*)pTemplate->OpenDocumentFile(NULL);
888 ASSERT_KINDOF(T42Document,pDoc);
889 pDoc->Talk(entry.m_Callee,entry.m_Caller,NULL);
890 entry.m_Status=CT42CallLogEntry::statusProcessed;
891 VERIFY(app->UpdateT42Call(entry));
892 m_CallsCtl.Update(item);
893}
894
895void CT42Dlg::OnCalllogDelete()
896{
897CT42App* app = (CT42App*)AfxGetApp();
898int ii = m_CallsCtl.GetItemCount();
899 if(ii<=0)
900 return;
901Klever::CBitSet bs(ii);
902 for(int i=0;i<ii;i++)
903 if(m_CallsCtl.GetItemState(i,LVIS_FOCUSED|LVIS_SELECTED))
904 bs.BitSet(i);
905 for(i = (ii-1);i>=0;i--){
906 if(!bs.IsSet(i))
907 continue;
908 CT42CallLogEntry entry;
909 VERIFY(app->GetT42Call(i,entry));
910 VERIFY(app->DelT42Call(entry.m_Time));
911 }
912}
913
914void CT42Dlg::OnCalllogSavetofile()
915{
916CT42App* app = (CT42App*)AfxGetApp();
917CT42CallLogEntry entry;
918CString filter;
919 VERIFY(filter.LoadString(IDS_FILTER_RTF));
920CFileDialog fd(FALSE,".rtf",NULL,
921 OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER|
922 OFN_LONGNAMES|OFN_NOREADONLYRETURN|OFN_PATHMUSTEXIST,
923 filter,this
924 );
925 if(fd.DoModal()==IDOK){
926 int ii = m_CallsCtl.GetItemCount();
927 if(ii<=0)
928 return;
929 Klever::CBitSet bs(ii);
930 for(int i=0;i<ii;i++)
931 if(m_CallsCtl.GetItemState(i,LVIS_FOCUSED|LVIS_SELECTED))
932 bs.BitSet(i);
933 try{
934 CStdioFile f(fd.GetPathName(),
935 CFile::modeCreate|CFile::modeWrite|CFile::shareDenyWrite|
936 CFile::typeText);
937 f.WriteString("{\\rtf1\\ansi\n");
938 for(i = (ii-1);i>=0;i--){
939 if(!bs.IsSet(i))
940 continue;
941 CT42CallLogEntry entry;
942 VERIFY(app->GetT42Call(i,entry));
943 CString tmp;
944 tmp.Format(IDS_FORMAT_T42CALLHEADER,
945 entry.m_Time.Format(IDS_FORMAT_CALLTIMELONG),
946 entry.m_Caller, entry.m_Callee,
947 entry.m_Duration.Format(IDS_FORMAT_CALLDURATION)
948 );
949 f.WriteString(tmp);
950 f.WriteString(entry.m_Message);
951 }
952 f.WriteString("\n}\n");
953 }catch(CException* e){
954 TRACE0("Save exc\n");
955 e->Delete();
956 }
957 }
958}
959
960void CT42Dlg::OnCalllogEmptylog()
961{
962CT42App* app = (CT42App*)AfxGetApp();
963int ii = m_CallsCtl.GetItemCount();
964 if(ii<=0)
965 return;
966 for(int i = (ii-1);i>=0;i--){
967 CT42CallLogEntry entry;
968 VERIFY(app->GetT42Call(i,entry));
969 VERIFY(app->DelT42Call(entry.m_Time));
970 }
971}
972
973void CT42Dlg::OnDeleteitemCalls(NMHDR* pNMHDR, LRESULT* pResult)
974{
975 NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
976 PostMessage(WM_UPDATEPREVIEW,(WPARAM)-1);
977 *pResult = 0;
978}
979
980LRESULT CT42Dlg::OnUpdatePreview(WPARAM wP,LPARAM)
981{
982int iItem = (int)wP;
983 if(iItem<0)
984 iItem = m_CallsCtl.GetNextItem(-1,LVNI_ALL|LVNI_FOCUSED);
985CT42App* app = (CT42App*)AfxGetApp();
986CT42CallLogEntry entry;
987 if(iItem<0 ||!app->GetT42Call(iItem,entry)){
988 m_PreviewCtl.SetWindowText("");
989 return 0;
990 }
991EDITSTREAM es;
992 memset(&es,0,sizeof(es));
993 es.dwCookie = (DWORD)&entry.m_Message;
994 es.pfnCallback = ESOUTProc;
995 m_PreviewCtl.StreamIn(SF_RTF,es);
996 return 0;
997}
998
999void CT42Dlg::OnKeydownCalls(NMHDR* pNMHDR, LRESULT* pResult)
1000{
1001 LV_KEYDOWN* pLVKeyDow = (LV_KEYDOWN*)pNMHDR;
1002
1003 switch(pLVKeyDow->wVKey){
1004 case 'R':
1005 if(GetKeyState(VK_CONTROL)&0x8000)
1006 OnCalllogCallback();
1007 break;
1008 case VK_DELETE:
1009 OnCalllogDelete();
1010 break;
1011 case 'D':
1012 if(GetKeyState(VK_CONTROL)&0x8000)
1013 OnCalllogDelete();
1014 break;
1015 }
1016 *pResult = 0;
1017}
1018
1019BOOL CT42Dlg::PreCreateWindow(CREATESTRUCT& cs)
1020{
1021 m_hExFW = ::GetForegroundWindow();
1022 return CDialog::PreCreateWindow(cs);
1023}
1024
1025void CT42Dlg::SetTheIcon(HICON hIcon)
1026{
1027 m_hIcon = hIcon;
1028 SetIcon(m_hIcon, TRUE); // Set big icon
1029 SetIcon(m_hIcon, FALSE); // Set small icon
1030NOTIFYICONDATA nid;
1031 memset(&nid,0,sizeof(nid));
1032 nid.cbSize = sizeof(nid);
1033 nid.hWnd = m_hWnd;
1034 nid.uID = IDC_TRAYICON;
1035 nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
1036 nid.uCallbackMessage=WM_TRAYICON;
1037 nid.hIcon = hIcon;
1038 if(m_newCalls)
1039 _snprintf(nid.szTip,sizeof(nid.szTip)-1,"%d new calls waiting",m_newCalls);
1040 else
1041 strcpy(nid.szTip,"Tea For Two");
1042 VERIFY(Shell_NotifyIcon(NIM_MODIFY,&nid));
1043}
1044
1045void CT42Dlg::OnShowWindow(BOOL bShow, UINT nStatus)
1046{
1047 CDialog::OnShowWindow(bShow, nStatus);
1048 if(bShow){
1049 m_newCalls=0;
1050 SetTheIcon(m_hIconEmpty);
1051 }
1052}
1053
1054void CT42Dlg::OnCalllogMarkasnew()
1055{
1056CT42App* app = (CT42App*)AfxGetApp();
1057int ii = m_CallsCtl.GetItemCount();
1058 if(ii<=0)
1059 return;
1060Klever::CBitSet bs(ii);
1061 for(int i=0;i<ii;i++)
1062 if(m_CallsCtl.GetItemState(i,LVIS_FOCUSED|LVIS_SELECTED))
1063 bs.BitSet(i);
1064int f = -1,t = -1;
1065 for(i = 0;i<ii;i++){
1066 if(!bs.IsSet(i))
1067 continue;
1068 CT42CallLogEntry entry;
1069 VERIFY(app->GetT42Call(i,entry));
1070 if(entry.m_Status==CT42CallLogEntry::statusProcessed){
1071 entry.m_Status=CT42CallLogEntry::statusOk;
1072 VERIFY(app->UpdateT42Call(entry));
1073 if(f<0)
1074 f=i;
1075 if(t<i)
1076 t=i;
1077 }
1078 }
1079 if(f<0 || t<0)
1080 return;
1081 m_CallsCtl.RedrawItems(f,t);
1082 m_CallsCtl.Invalidate();
1083}
1084
1085void CT42Dlg::OnCalllogMarkasprocessed()
1086{
1087CT42App* app = (CT42App*)AfxGetApp();
1088int ii = m_CallsCtl.GetItemCount();
1089 if(ii<=0)
1090 return;
1091Klever::CBitSet bs(ii);
1092 for(int i=0;i<ii;i++)
1093 if(m_CallsCtl.GetItemState(i,LVIS_FOCUSED|LVIS_SELECTED))
1094 bs.BitSet(i);
1095int f = -1,t = -1;
1096 for(i = 0;i<ii;i++){
1097 if(!bs.IsSet(i))
1098 continue;
1099 CT42CallLogEntry entry;
1100 VERIFY(app->GetT42Call(i,entry));
1101 if(entry.m_Status!=CT42CallLogEntry::statusProcessed){
1102 entry.m_Status=CT42CallLogEntry::statusProcessed;
1103 VERIFY(app->UpdateT42Call(entry));
1104 if(f<0)
1105 f=i;
1106 if(t<i)
1107 t=i;
1108 }
1109 }
1110 if(f<0 || t<0)
1111 return;
1112 m_CallsCtl.RedrawItems(f,t);
1113 m_CallsCtl.Invalidate();
1114}
1115
1116void CT42Dlg::RecalcLayout()
1117{
1118CRect crc;
1119 GetClientRect(&crc);
1120CRect rcCalls;
1121 m_CallsCtl.GetWindowRect(&rcCalls);
1122 ScreenToClient(rcCalls);
1123 // Calculate windows height.
1124UINT wHeight = (crc.Height()-rcCalls.top-m_marginY-m_gapY)/2;
1125UINT wWidth = crc.Width()-(2*m_marginX);
1126 // Position windows
1127 m_CallsCtl.SetWindowPos(
1128 NULL,
1129 m_marginX,rcCalls.top-crc.top, wWidth,wHeight,
1130 SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOZORDER
1131 );
1132 m_PreviewCtl.SetWindowPos(
1133 NULL,
1134 m_marginX,rcCalls.top-crc.top+wHeight+m_gapY, wWidth,wHeight,
1135 SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOZORDER
1136 );
1137
1138CRect brc;
1139 m_TeaCtl.GetWindowRect(brc); ScreenToClient(brc);
1140UINT bX = crc.Width()-m_marginX-brc.Width();
1141 m_TeaCtl.SetWindowPos(NULL,bX,brc.top, 0,0,SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER|SWP_NOCOPYBITS);
1142 m_OptionsCtl.GetWindowRect(brc); ScreenToClient(brc);
1143 m_OptionsCtl.SetWindowPos(NULL,bX,brc.top,0,0,SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER|SWP_NOCOPYBITS);
1144 m_ExitCtl.GetWindowRect(brc); ScreenToClient(brc);
1145 m_ExitCtl.SetWindowPos(NULL,bX,brc.top,0,0,SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER|SWP_NOCOPYBITS);
1146 m_HelpCtl.GetWindowRect(brc); ScreenToClient(brc);
1147 m_HelpCtl.SetWindowPos(NULL,bX,brc.top,0,0,SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOSIZE|SWP_NOZORDER|SWP_NOCOPYBITS);
1148}
1149
1150void CT42Dlg::OnSize(UINT nType, int cx, int cy)
1151{
1152 CDialog::OnSize(nType, cx, cy);
1153
1154 if(m_marginX && m_marginY && m_gapY){
1155 RecalcLayout();
1156 SetColumnWidths();
1157 }
1158
1159}
1160
1161void CT42Dlg::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
1162{
1163 if(m_sizeMin.cx && m_sizeMin.cy){
1164 lpMMI->ptMinTrackSize.x = m_sizeMin.cx;
1165 lpMMI->ptMinTrackSize.y = m_sizeMin.cy;
1166 }
1167
1168 CDialog::OnGetMinMaxInfo(lpMMI);
1169}
1170
1171void CT42Dlg::SetOnCtl(UINT nAction,CComboBox& ctl)
1172{
1173int n = 0;
1174 switch(nAction){
1175 case IDC_SECRETARY: n = 1; break;
1176 case IDC_NOTHERE: n = 2; break;
1177 case IDC_REFUSE: n = 3; break;
1178 case IDCANCEL: n = 4; break;
1179 }
1180 ctl.SetCurSel(n);
1181}
1182
1183UINT CT42Dlg::GetOnCtl(CComboBox& ctl)
1184{
1185 switch(ctl.GetCurSel()){
1186 case 1: return IDC_SECRETARY;
1187 case 2: return IDC_NOTHERE;
1188 case 3: return IDC_REFUSE;
1189 case 4: return IDCANCEL;
1190 }
1191 return 0;
1192}
1193
1194void CT42Dlg::OnAway()
1195{
1196 m_bAway = m_AwayCtl.GetCheck();
1197}
1198void CT42Dlg::OnSelendokOncall()
1199{
1200 m_onCall = GetOnCtl(m_OnCallCtl);
1201}
1202void CT42Dlg::OnSelendokOncallaway()
1203{
1204 m_onCallAway = GetOnCtl(m_OnCallAwayCtl);
1205}
1206
1207void CT42Dlg::LoadSettings()
1208{
1209CT42App* app = (CT42App*)AfxGetApp();
1210 m_onCall = app->GetProfileInt("Settings","T42OnCall",m_onCall);
1211 m_onCallAway = app->GetProfileInt("Settings","T42OnCallAway",m_onCallAway);
1212}
1213
1214void CT42Dlg::SaveSettings()
1215{
1216CT42App* app = (CT42App*)AfxGetApp();
1217 app->WriteProfileInt("Settings","T42OnCall",m_onCall);
1218 app->WriteProfileInt("Settings","T42OnCallAway",m_onCallAway);
1219}
1220
1221void CT42Dlg::OnTrayAway()
1222{
1223 m_AwayCtl.SetCheck((m_bAway=!m_bAway)?1:0);
1224}
1225
1226void CT42Dlg::OnTimer(UINT nIDEvent)
1227{
1228 if(nIDEvent==timerMinutes){
1229 KillTimer(timerMinutes);
1230 CDocTemplate* pTemplate = ((CT42App*)AfxGetApp())->m_pTemplate;
1231 POSITION p = pTemplate->GetFirstDocPosition();
1232 while(p){
1233 T42Document* pDoc = (T42Document*)pTemplate->GetNextDoc(p);
1234 pDoc->OnMinute();
1235 }
1236 SetTimer(timerMinutes,60000,NULL);
1237 }
1238
1239 CDialog::OnTimer(nIDEvent);
1240}
1241
1242BOOL CT42Dlg::OnQueryEndSession()
1243{
1244 if (!CDialog::OnQueryEndSession())
1245 return FALSE;
1246
1247CT42App* app = (CT42App*)AfxGetApp();
1248 app->SaveSettings();
1249
1250 return TRUE;
1251}