- Added user database locking/unlocking
[public/netxms.git] / src / console / win32 / nxcon.cpp
CommitLineData
3bf7e95e
VK
1// nxcon.cpp : Defines the class behaviors for the application.
2//
3
4#include "stdafx.h"
5#include "nxcon.h"
6
7#include "MainFrm.h"
8#include "LoginDialog.h"
9
10#ifdef _DEBUG
11#define new DEBUG_NEW
12#undef THIS_FILE
13static char THIS_FILE[] = __FILE__;
14#endif
15
16
17//
18// Wrapper for client library event handler
19//
20
21static void ClientEventHandler(DWORD dwEvent, DWORD dwCode, void *pArg)
22{
23 theApp.EventHandler(dwEvent, dwCode, pArg);
24}
25
26
8e748b3e
VK
27//
28// Wrapper for client library debug callback
29//
30
31static void ClientDebugCallback(char *pszMsg)
32{
33 theApp.DebugCallback(pszMsg);
34}
35
36
3bf7e95e
VK
37//
38// CConsoleApp
39//
40
41BEGIN_MESSAGE_MAP(CConsoleApp, CWinApp)
42 //{{AFX_MSG_MAP(CConsoleApp)
43 ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
44 ON_COMMAND(ID_VIEW_CONTROLPANEL, OnViewControlpanel)
45 ON_COMMAND(ID_VIEW_EVENTS, OnViewEvents)
46 ON_COMMAND(ID_VIEW_MAP, OnViewMap)
47 ON_COMMAND(ID_CONNECT_TO_SERVER, OnConnectToServer)
48 ON_COMMAND(ID_VIEW_OBJECTBROWSER, OnViewObjectbrowser)
a5f8f9b0 49 ON_COMMAND(ID_CONTROLPANEL_EVENTS, OnControlpanelEvents)
8e748b3e 50 ON_COMMAND(ID_VIEW_DEBUG, OnViewDebug)
3bf7e95e
VK
51 //}}AFX_MSG_MAP
52END_MESSAGE_MAP()
53
54
55//
56// CConsoleApp construction
57//
58
59CConsoleApp::CConsoleApp()
60{
61 m_bCtrlPanelActive = FALSE;
62 m_bEventBrowserActive = FALSE;
a5f8f9b0 63 m_bEventEditorActive = FALSE;
3bf7e95e 64 m_bObjectBrowserActive = FALSE;
8e748b3e 65 m_bDebugWindowActive = FALSE;
3bf7e95e 66 m_dwClientState = STATE_DISCONNECTED;
a5f8f9b0 67 m_pRqWaitList = NULL;
999bd324
VK
68 m_dwRqWaitListSize = 0;
69 m_mutexRqWaitList = MutexCreate();
3bf7e95e
VK
70}
71
999bd324
VK
72
73//
74// CConsoleApp destruction
75//
76
77CConsoleApp::~CConsoleApp()
78{
79 if (m_pRqWaitList != NULL)
80 MemFree(m_pRqWaitList);
81 MutexDestroy(m_mutexRqWaitList);
82}
83
84
3bf7e95e
VK
85//
86// The one and only CConsoleApp object
87//
88
89CConsoleApp theApp;
90
91
92//
93// CConsoleApp initialization
94//
95
96BOOL CConsoleApp::InitInstance()
97{
98 BOOL bSetWindowPos;
99 DWORD dwBytes;
100 BYTE *pData;
8e748b3e 101 HMENU hMenu;
3bf7e95e
VK
102
103 if (!AfxSocketInit())
104 {
105 AfxMessageBox(IDP_SOCKETS_INIT_FAILED, MB_OK | MB_ICONSTOP);
106 return FALSE;
107 }
108
109 if (!NXCInitialize())
110 {
111 AfxMessageBox(IDS_NXC_INIT_FAILED, MB_OK | MB_ICONSTOP);
112 return FALSE;
113 }
114 NXCSetEventHandler(ClientEventHandler);
115
116 AfxEnableControlContainer();
117
118 // Standard initialization
119 // If you are not using these features and wish to reduce the size
120 // of your final executable, you should remove from the following
121 // the specific initialization routines you do not need.
122
123#ifdef _AFXDLL
124 Enable3dControls(); // Call this when using MFC in a shared DLL
125#else
126 Enable3dControlsStatic(); // Call this when linking to MFC statically
127#endif
128
129 // Change the registry key under which our settings are stored.
130 SetRegistryKey(_T("NetXMS"));
131
132 // To create the main window, this code creates a new frame window
133 // object and then sets it as the application's main window object.
134
135 CMDIFrameWnd* pFrame = new CMainFrame;
136 m_pMainWnd = pFrame;
137
138 // create main MDI frame window
139 if (!pFrame->LoadFrame(IDR_MAINFRAME))
140 return FALSE;
141
8e748b3e
VK
142 // Load shared MDI menus and accelerator table
143 HINSTANCE hInstance = AfxGetResourceHandle();
144
145 hMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDM_VIEW_SPECIFIC));
146
147 m_hMDIMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));
148 InsertMenu(m_hMDIMenu, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)GetSubMenu(hMenu, 0), "&Window");
149
150 m_hEventBrowserMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));
151 InsertMenu(m_hEventBrowserMenu, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)GetSubMenu(hMenu, 0), "&Window");
152 InsertMenu(m_hEventBrowserMenu, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)GetSubMenu(hMenu, 1), "&Event");
153
2060ba91
VK
154 m_hObjectBrowserMenu = ::LoadMenu(hInstance, MAKEINTRESOURCE(IDR_MAINFRAME));
155 InsertMenu(m_hObjectBrowserMenu, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)GetSubMenu(hMenu, 0), "&Window");
156 InsertMenu(m_hObjectBrowserMenu, 3, MF_BYPOSITION | MF_POPUP, (UINT_PTR)GetSubMenu(hMenu, 2), "&Object");
157
8e748b3e
VK
158 m_hMDIAccel = ::LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_MDI_DEFAULT));
159 m_hEventBrowserAccel = ::LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_MDI_DEFAULT));
2060ba91 160 m_hObjectBrowserAccel = ::LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_OBJECT_BROWSER));
3bf7e95e
VK
161
162 // Load configuration from registry
163 dwBytes = sizeof(WINDOWPLACEMENT);
164 bSetWindowPos = GetProfileBinary(_T("General"), _T("WindowPlacement"),
165 &pData, (UINT *)&dwBytes);
166 strcpy(g_szServer, (LPCTSTR)GetProfileString(_T("Connection"), _T("Server"), _T("localhost")));
167 strcpy(g_szLogin, (LPCTSTR)GetProfileString(_T("Connection"), _T("Login"), NULL));
168
169 // The main window has been initialized, so show and update it.
170 if (bSetWindowPos)
171 {
172 pFrame->SetWindowPlacement((WINDOWPLACEMENT *)pData);
173 if (pFrame->IsIconic())
174 pFrame->ShowWindow(SW_RESTORE);
175 }
176 else
177 {
178 pFrame->ShowWindow(m_nCmdShow);
179 }
180 pFrame->UpdateWindow();
181 pFrame->PostMessage(WM_COMMAND, ID_CONNECT_TO_SERVER, 0);
182
183 return TRUE;
184}
185
186/////////////////////////////////////////////////////////////////////////////
187// CConsoleApp message handlers
188
189int CConsoleApp::ExitInstance()
190{
8e748b3e
VK
191 NXCSetDebugCallback(NULL);
192 NXCDisconnect();
193
3bf7e95e 194 // Free resources
8e748b3e
VK
195 SafeFreeResource(m_hMDIMenu);
196 SafeFreeResource(m_hMDIAccel);
197 SafeFreeResource(m_hEventBrowserMenu);
198 SafeFreeResource(m_hEventBrowserAccel);
3bf7e95e
VK
199
200 return CWinApp::ExitInstance();
201}
202
203
204/////////////////////////////////////////////////////////////////////////////
205// CAboutDlg dialog used for App About
206
207class CAboutDlg : public CDialog
208{
209public:
210 CAboutDlg();
211
212// Dialog Data
213 //{{AFX_DATA(CAboutDlg)
214 enum { IDD = IDD_ABOUTBOX };
215 //}}AFX_DATA
216
217 // ClassWizard generated virtual function overrides
218 //{{AFX_VIRTUAL(CAboutDlg)
219 protected:
220 virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
221 //}}AFX_VIRTUAL
222
223// Implementation
224protected:
225 //{{AFX_MSG(CAboutDlg)
226 // No message handlers
227 //}}AFX_MSG
228 DECLARE_MESSAGE_MAP()
229};
230
231CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
232{
233 //{{AFX_DATA_INIT(CAboutDlg)
234 //}}AFX_DATA_INIT
235}
236
237void CAboutDlg::DoDataExchange(CDataExchange* pDX)
238{
239 CDialog::DoDataExchange(pDX);
240 //{{AFX_DATA_MAP(CAboutDlg)
241 //}}AFX_DATA_MAP
242}
243
244BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
245 //{{AFX_MSG_MAP(CAboutDlg)
246 // No message handlers
247 //}}AFX_MSG_MAP
248END_MESSAGE_MAP()
249
250// App command to run the dialog
251void CConsoleApp::OnAppAbout()
252{
253 CAboutDlg aboutDlg;
254 aboutDlg.DoModal();
255}
256
257/////////////////////////////////////////////////////////////////////////////
258// CConsoleApp message handlers
259
260
261void CConsoleApp::OnViewControlpanel()
262{
263 CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
264
265 // create a new MDI child window or open existing
266 if (m_bCtrlPanelActive)
267 m_pwndCtrlPanel->BringWindowToTop();
268 else
269 pFrame->CreateNewChild(
8e748b3e 270 RUNTIME_CLASS(CControlPanel), IDR_CTRLPANEL, m_hMDIMenu, m_hMDIAccel);
3bf7e95e
VK
271}
272
273
274//
275// This method called when new view is created
276//
277
278void CConsoleApp::OnViewCreate(DWORD dwView, CWnd *pWnd)
279{
280 switch(dwView)
281 {
282 case IDR_CTRLPANEL:
283 m_bCtrlPanelActive = TRUE;
284 m_pwndCtrlPanel = pWnd;
285 break;
286 case IDR_EVENTS:
287 m_bEventBrowserActive = TRUE;
288 m_pwndEventBrowser = (CEventBrowser *)pWnd;
289 break;
290 case IDR_OBJECTS:
291 m_bObjectBrowserActive = TRUE;
292 m_pwndObjectBrowser = pWnd;
293 break;
a5f8f9b0
VK
294 case IDR_EVENT_EDITOR:
295 m_bEventEditorActive = TRUE;
296 m_pwndEventEditor = (CEventEditor *)pWnd;
297 break;
8e748b3e
VK
298 case IDR_DEBUG_WINDOW:
299 m_bDebugWindowActive = TRUE;
300 m_pwndDebugWindow = (CDebugFrame *)pWnd;
301 NXCSetDebugCallback(ClientDebugCallback);
302 break;
3bf7e95e
VK
303 default:
304 break;
305 }
306}
307
308
309//
310// This method called when view is destroyed
311//
312
313void CConsoleApp::OnViewDestroy(DWORD dwView, CWnd *pWnd)
314{
315 switch(dwView)
316 {
317 case IDR_CTRLPANEL:
318 m_bCtrlPanelActive = FALSE;
319 break;
320 case IDR_EVENTS:
321 m_bEventBrowserActive = FALSE;
322 break;
323 case IDR_OBJECTS:
324 m_bObjectBrowserActive = FALSE;
325 break;
a5f8f9b0
VK
326 case IDR_EVENT_EDITOR:
327 m_bEventEditorActive = FALSE;
328 break;
8e748b3e
VK
329 case IDR_DEBUG_WINDOW:
330 m_bDebugWindowActive = FALSE;
331 NXCSetDebugCallback(NULL);
332 break;
3bf7e95e
VK
333 default:
334 break;
335 }
336}
337
338void CConsoleApp::OnViewEvents()
339{
340 CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
341
342 // create a new MDI child window or open existing
343 if (m_bEventBrowserActive)
344 m_pwndEventBrowser->BringWindowToTop();
345 else
346 pFrame->CreateNewChild(
8e748b3e 347 RUNTIME_CLASS(CEventBrowser), IDR_EVENTS, m_hEventBrowserMenu, m_hEventBrowserAccel);
3bf7e95e
VK
348}
349
350void CConsoleApp::OnViewMap()
351{
352 CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
353
354 // create a new MDI child window
89d4d2a2
VK
355// pFrame->CreateNewChild(RUNTIME_CLASS(CMapFrame), IDR_MAPFRAME, m_hMDIMenu, m_hMDIAccel);
356pFrame->BroadcastMessage(WM_OBJECT_CHANGE, 1, 0);
3bf7e95e
VK
357}
358
359void CConsoleApp::OnConnectToServer()
360{
361 CLoginDialog dlgLogin;
362
363 dlgLogin.m_szServer = g_szServer;
364 dlgLogin.m_szLogin = g_szLogin;
365 while(1)
366 {
367 if (dlgLogin.DoModal() != IDOK)
368 {
369 PostQuitMessage(1);
370 break;
371 }
372 strcpy(g_szServer, (LPCTSTR)dlgLogin.m_szServer);
373 strcpy(g_szLogin, (LPCTSTR)dlgLogin.m_szLogin);
374 strcpy(g_szPassword, (LPCTSTR)dlgLogin.m_szPassword);
375
376 // Save last connection parameters
377 WriteProfileString(_T("Connection"), _T("Server"), g_szServer);
378 WriteProfileString(_T("Connection"), _T("Login"), g_szLogin);
379
380 // Initiate connection
381 m_bAuthFailed = FALSE;
382 if (NXCConnect(g_szServer, g_szLogin, g_szPassword))
383 {
384 m_dlgProgress.m_szStatusText = "Connecting to server...";
385 if (m_dlgProgress.DoModal() == IDOK)
386 {
387 // Now we are connected, request data sync
388 NXCSyncObjects();
8e2809bb 389 NXCLoadUserDB();
3bf7e95e
VK
390 break;
391 }
392 else
393 m_pMainWnd->MessageBox(m_bAuthFailed ? "Client authentication failed (invalid login name or password)" :
394 "Unable to establish connection with the server",
395 "Connection error", MB_OK | MB_ICONSTOP);
396 }
397 else
398 {
399 m_pMainWnd->MessageBox("Unable to initiate connection to server",
400 "Connection error", MB_OK | MB_ICONSTOP);
401 }
402 }
403}
404
405void CConsoleApp::OnViewObjectbrowser()
406{
407 CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
408
409 // create a new MDI child window or open existing
410 if (m_bObjectBrowserActive)
411 m_pwndObjectBrowser->BringWindowToTop();
412 else
413 pFrame->CreateNewChild(
2060ba91 414 RUNTIME_CLASS(CObjectBrowser), IDR_OBJECTS, m_hObjectBrowserMenu, m_hObjectBrowserAccel);
3bf7e95e
VK
415}
416
417
418//
419// Event handler for client libray events
420//
421
422void CConsoleApp::EventHandler(DWORD dwEvent, DWORD dwCode, void *pArg)
423{
424 static BOOL bNowConnecting = FALSE;
425 CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
426
427 switch(dwEvent)
428 {
429 case NXC_EVENT_STATE_CHANGED:
430 switch(dwCode)
431 {
432 case STATE_CONNECTING:
433 bNowConnecting = TRUE;
434 break;
435 case STATE_IDLE:
436 if (bNowConnecting)
437 {
6aaf0c07 438 m_dlgProgress.Terminate(IDOK);
3bf7e95e
VK
439 bNowConnecting = FALSE;
440 }
441 if ((m_bEventBrowserActive) && (m_dwClientState == STATE_SYNC_EVENTS))
442 m_pwndEventBrowser->EnableDisplay(TRUE);
443 break;
444 case STATE_DISCONNECTED:
445 if (bNowConnecting)
446 {
6aaf0c07 447 m_dlgProgress.Terminate(IDCANCEL);
3bf7e95e
VK
448 bNowConnecting = FALSE;
449 }
450 break;
451 case STATE_SYNC_EVENTS:
452 if (m_bEventBrowserActive)
453 m_pwndEventBrowser->EnableDisplay(FALSE);
454 break;
455 default:
456 break;
457 }
458 m_dwClientState = dwCode;
459 break;
460 case NXC_EVENT_LOGIN_RESULT:
461 if (dwCode == 0)
462 m_bAuthFailed = TRUE;
463 break;
464 case NXC_EVENT_NEW_ELOG_RECORD:
465 if (m_bEventBrowserActive)
466 m_pwndEventBrowser->AddEvent((NXC_EVENT *)pArg);
467 MemFree(pArg);
3bf7e95e 468 break;
a5f8f9b0 469 case NXC_EVENT_REQUEST_COMPLETED:
999bd324 470 OnRequestComplete(dwCode, (DWORD)pArg);
a5f8f9b0 471 break;
89d4d2a2
VK
472 case NXC_EVENT_OBJECT_CHANGED:
473 ((CMainFrame *)m_pMainWnd)->PostMessage(WM_OBJECT_CHANGE, dwCode, (LPARAM)pArg);
474 break;
3bf7e95e
VK
475 default:
476 break;
477 }
478}
a5f8f9b0 479
999bd324
VK
480
481//
482// Handler for WM_COMMAND(ID_CONTROLPANEL_EVENTS) message
483//
484
a5f8f9b0
VK
485void CConsoleApp::OnControlpanelEvents()
486{
487 CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
488
489 // create a new MDI child window or open existing
490 if (m_bEventEditorActive)
491 m_pwndEventEditor->BringWindowToTop();
492 else
493 pFrame->CreateNewChild(
f6d9527a 494 RUNTIME_CLASS(CEventEditor), IDR_EVENT_EDITOR, m_hMDIMenu, m_hMDIAccel);
a5f8f9b0
VK
495}
496
497
498//
499// Register callback for request completion
500//
501
502void CConsoleApp::RegisterRequest(HREQUEST hRequest, CWnd *pWnd)
503{
f6d9527a 504 MutexLock(m_mutexRqWaitList, INFINITE);
999bd324
VK
505 m_pRqWaitList = (RQ_WAIT_INFO *)MemReAlloc(m_pRqWaitList, sizeof(RQ_WAIT_INFO) * (m_dwRqWaitListSize + 1));
506 m_pRqWaitList[m_dwRqWaitListSize].hRequest = hRequest;
507 m_pRqWaitList[m_dwRqWaitListSize].pWnd = pWnd;
508 m_dwRqWaitListSize++;
f6d9527a 509 MutexUnlock(m_mutexRqWaitList);
999bd324
VK
510}
511
512
513//
514// This method called by client library event handler on NXC_EVENT_REQUEST_COMPLETE
515//
516
517void CConsoleApp::OnRequestComplete(HREQUEST hRequest, DWORD dwRetCode)
518{
519 DWORD i;
a5f8f9b0 520
f6d9527a 521 MutexLock(m_mutexRqWaitList, INFINITE);
999bd324
VK
522 for(i = 0; i < m_dwRqWaitListSize; i++)
523 if (m_pRqWaitList[i].hRequest == hRequest)
524 {
525 m_pRqWaitList[i].pWnd->SendMessage(WM_REQUEST_COMPLETED, hRequest, dwRetCode);
526 m_dwRqWaitListSize--;
527 memmove(&m_pRqWaitList[i], &m_pRqWaitList[i + 1], sizeof(RQ_WAIT_INFO) * (m_dwRqWaitListSize - i));
528 i--;
529 }
f6d9527a 530 MutexUnlock(m_mutexRqWaitList);
a5f8f9b0 531}
8e748b3e
VK
532
533
534//
535// Handler for WM_COMMAND::ID_VIEW_DEBUG message
536//
537
538void CConsoleApp::OnViewDebug()
539{
540 CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
541
542 // create a new MDI child window or open existing
543 if (m_bDebugWindowActive)
544 m_pwndDebugWindow->BringWindowToTop();
545 else
546 pFrame->CreateNewChild(
547 RUNTIME_CLASS(CDebugFrame), IDR_DEBUG_WINDOW, m_hMDIMenu, m_hMDIAccel);
548}
89d4d2a2
VK
549
550
551//
552// Print debug information
553//
554
555void CConsoleApp::DebugPrintf(char *szFormat, ...)
556{
557 if (m_bDebugWindowActive)
558 {
559 char szBuffer[1024];
560 va_list args;
561
562 va_start(args, szFormat);
563 vsprintf(szBuffer, szFormat, args);
564 va_end(args);
565
566 m_pwndDebugWindow->AddMessage(szBuffer);
567 }
568}
2057008d
VK
569
570
571//
572// Edit properties of specific object
573//
574
575void CConsoleApp::ObjectProperties(DWORD dwObjectId)
576{
577 CObjectPropSheet wndPropSheet("Object Properties", GetMainWnd(), 0);
578 CNodePropsGeneral wndNodeGeneral;
8e2809bb 579 CObjectPropsGeneral wndObjectGeneral;
2057008d 580 CObjectPropCaps wndObjectCaps;
8e2809bb 581 CObjectPropsSecurity wndObjectSecurity;
2057008d
VK
582 NXC_OBJECT *pObject;
583 char szBuffer[32];
584
585 pObject = NXCFindObjectById(dwObjectId);
586 if (pObject != NULL)
587 {
588 // Create "General" tab
8e2809bb 589 if (pObject->iClass == OBJECT_NODE)
2057008d 590 {
8e2809bb
VK
591 wndNodeGeneral.m_dwObjectId = dwObjectId;
592 wndNodeGeneral.m_strName = pObject->szName;
593 wndNodeGeneral.m_strOID = pObject->node.szObjectId;
594 wndNodeGeneral.m_strPrimaryIp = IpToStr(pObject->dwIpAddr, szBuffer);
595 wndNodeGeneral.m_iAgentPort = (int)pObject->node.wAgentPort;
596 wndNodeGeneral.m_strCommunity = pObject->node.szCommunityString;
597 wndNodeGeneral.m_iAuthType = pObject->node.wAuthMethod;
598 wndNodeGeneral.m_strSecret = pObject->node.szSharedSecret;
599 wndPropSheet.AddPage(&wndNodeGeneral);
600 }
601 else
602 {
603 wndObjectGeneral.m_dwObjectId = dwObjectId;
604 wndObjectGeneral.m_strClass = g_szObjectClass[pObject->iClass];
605 wndObjectGeneral.m_strName = pObject->szName;
606 wndPropSheet.AddPage(&wndObjectGeneral);
2057008d
VK
607 }
608
609 // Create tabs specific for node objects
610 if (pObject->iClass == OBJECT_NODE)
611 {
612 // Create "Capabilities" tab
613 wndObjectCaps.m_pObject = pObject;
614 wndPropSheet.AddPage(&wndObjectCaps);
615 }
616
f6d9527a 617 // Create "Security" tab
8e2809bb
VK
618 wndObjectSecurity.m_pObject = pObject;
619 wndObjectSecurity.m_bInheritRights = pObject->bInheritRights;
620 wndPropSheet.AddPage(&wndObjectSecurity);
f6d9527a
VK
621
622 wndPropSheet.SetObject(pObject);
623 if (wndPropSheet.DoModal() == IDOK)
624 wndPropSheet.SaveObjectChanges();
2057008d
VK
625 }
626}
f6d9527a
VK
627
628
629//
630// Wait for specific request
631//
632
633DWORD CConsoleApp::WaitForRequest(HREQUEST hRequest, char *pszMessage)
634{
635 CRequestProcessingDlg wndWaitDlg;
636
637 wndWaitDlg.m_hRequest = hRequest;
638 if (pszMessage != NULL)
639 wndWaitDlg.m_strInfoText = pszMessage;
640 else
641 wndWaitDlg.m_strInfoText = "Processing request...";
642 return (DWORD)wndWaitDlg.DoModal();
643}