2
* mfcapp.cpp -- $Id: mfcapp.cpp 685 2003-03-08 15:26:51Z travo $
3
* MFC implementation of play, boss and worker thread classes
5
* Copyright (c) 2000. See accompanying LEGAL file for details.
15
static int w_result = 0;
17
static CWinThread *the_worker = 0;
18
static CMultiDocTemplate *mfc_template = 0;
20
static void on_view(mfc_term_view *view);
21
static void on_update_view(mfc_term_view *view, CCmdUI *ui);
22
static int mfc_showing = 0;
23
static void mfc_show();
24
static char *mfc_cpy(HANDLE heap, const char *text, long len);
25
static int mfc_run_hack();
26
static int (*w_on_launch)(int, char **)= 0;
28
static void mfc_quit(void);
29
static int mfc_quitting = 0;
30
static HWND mfc_parent(int width, int height, char *title, int hints);
36
the_boss.m_pMainWnd->SendMessage(WM_CLOSE, 0, 0);
40
/*------------------------------------------------------------------------*/
41
/* boss thread (main application) */
43
class mfc_worker : public CWinThread {
44
DECLARE_DYNCREATE(mfc_worker)
47
virtual BOOL InitInstance();
49
virtual BOOL PreTranslateMessage(MSG* pmsg);
50
virtual BOOL OnIdle(LONG count);
51
virtual int ExitInstance();
55
BEGIN_MESSAGE_MAP(mfc_boss, CWinApp)
56
ON_COMMAND(ID_APP_ABOUT, on_about)
57
ON_COMMAND(ID_SIGINT, on_sigint)
58
ON_COMMAND(ID_VIEW_TERM, on_view_term)
59
ON_COMMAND(ID_VIEW_HIST, on_view_hist)
60
ON_UPDATE_COMMAND_UI(ID_VIEW_TERM, on_update_view_term)
61
ON_UPDATE_COMMAND_UI(ID_VIEW_HIST, on_update_view_hist)
62
ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
63
ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
64
ON_COMMAND(ID_FILE_PRINT_SETUP, CWinApp::OnFilePrintSetup)
67
static int w_argc = 0;
68
static char **w_argv = 0;
70
mfc_boss::mfc_boss(int (*on_launch)(int, char **))
72
w_on_launch = on_launch;
75
class mfc_frame_wnd : public CMDIFrameWnd
77
DECLARE_DYNCREATE(mfc_frame_wnd)
80
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
83
IMPLEMENT_DYNCREATE(mfc_frame_wnd, CMDIFrameWnd)
85
mfc_frame_wnd::mfc_frame_wnd()
90
mfc_frame_wnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
93
if (message==ID_CALL_FUNC) {
94
void (*func)(void *arg)= (void (*)(void *))lParam;
95
void *arg = (void *)wParam;
98
if (message==WM_QUERYNEWPALETTE && w_screen.active)
99
return ::SendMessage(w_screen.active->w, message, wParam, lParam);
100
result = CMDIFrameWnd::WindowProc(message, wParam, lParam);
106
mfc_boss::InitInstance()
108
if (!AfxOleInit()) { /* all this for richedit... */
109
AfxMessageBox(IDP_OLE_INIT_FAILED);
116
Enable3dControlsStatic();
119
SetRegistryKey(m_pszAppName); // AFX_IDS_APP_TITLE, considered IDR_MAINFRAME
120
LoadStdProfileSettings(10); // Load standard INI file options (including MRU)
123
new CMultiDocTemplate(IDR_EDITFRAME,
124
RUNTIME_CLASS(mfc_edit_doc),
125
RUNTIME_CLASS(mfc_edit_child),
126
RUNTIME_CLASS(mfc_edit_view));
127
AddDocTemplate(mfc_template);
129
/* create the main window, but don't show it until
130
* the terminal window or a graphics child window is created
131
* -- MFC Run method kills process if no main window */
132
CMDIFrameWnd* fw = new mfc_frame_wnd;
133
if (!fw->LoadFrame(IDR_MAINFRAME)) return 0;
135
m_pMainWnd->DragAcceptFiles();
138
RegisterShellFileTypes(0); /* do not register for printing */
140
/* some command line stuff needs to be merged with w_init... */
141
CCommandLineInfo cmd_info;
142
ParseCommandLine(cmd_info);
143
/* prevent opening an empty untitled document at startup */
144
if (cmd_info.m_nShellCommand == CCommandLineInfo::FileNew)
145
cmd_info.m_nShellCommand = CCommandLineInfo::FileNothing;
146
if (!ProcessShellCommand(cmd_info)) return 0;
149
AfxBeginThread(RUNTIME_CLASS(mfc_worker), THREAD_PRIORITY_BELOW_NORMAL);
154
mfc_boss::ExitInstance()
156
the_worker->PostThreadMessage(WM_QUIT,0,0);
163
CWinApp::ExitInstance();
170
CDialog about(IDD_ABOUTBOX);
175
mfc_boss::on_sigint()
178
if (!w_sigint(1)) mfc_quit();
182
mfc_boss::on_view_term()
188
mfc_boss::on_view_hist()
194
mfc_boss::on_update_view_term(CCmdUI *ui)
196
on_update_view(term_view, ui);
200
mfc_boss::on_update_view_hist(CCmdUI *ui)
202
on_update_view(hist_view, ui);
206
on_view(mfc_term_view *view)
208
if (view && IsWindow(view->m_hWnd)) {
209
CMDIFrameWnd *fw = (CMDIFrameWnd *)(the_boss.m_pMainWnd);
210
if (view->is_visible) {
211
CMDIChildWnd *cw = (CMDIChildWnd *)fw->GetActiveFrame();
212
if (view == cw->GetActiveView()) fw->MDINext();
213
view->GetParent()->ShowWindow(SW_HIDE);
215
view->GetParent()->ShowWindow(SW_SHOW);
216
fw->MDIActivate(view->GetParent());
218
view->is_visible = !view->is_visible;
219
SendMessage(fw->m_hWndMDIClient, WM_MDIREFRESHMENU, 0, 0);
224
on_update_view(mfc_term_view *view, CCmdUI *ui)
226
if (view && IsWindow(view->m_hWnd)) {
228
ui->SetCheck(view->is_visible);
234
/*------------------------------------------------------------------------*/
237
IMPLEMENT_DYNCREATE(mfc_worker, CWinThread)
239
mfc_worker::mfc_worker()
244
mfc_worker::InitInstance()
246
w_initialize(the_boss.m_hInstance, the_boss.m_pMainWnd->m_hWnd,
247
mfc_quit, mfc_stdinit, mfc_parent);
249
/* crack command line into argc, argv */
250
HANDLE heap = GetProcessHeap();
251
LPSTR cmd_line = the_boss.m_lpCmdLine;
252
char module_name[1028];
253
DWORD len = GetModuleFileName((HMODULE)0, module_name, 1024);
254
module_name[len] = '\0';
256
w_argv = (char**)HeapAlloc(heap, HEAP_GENERATE_EXCEPTIONS, sizeof(char *)*9);
257
w_argv[w_argc++] = mfc_cpy(heap, w_unixpath(module_name), len);
262
while (c[0]==' ' || c[0]=='\t' || c[0]=='\r' || c[0]=='\n') c++;
266
if (delim=='"' || delim=='\'') {
268
while (c[0] && c[0]!=delim) c++;
270
while (c[0] && c[0]!=' ' && c[0]!='\t' &&
271
c[0]!='\r' && c[0]!='\n') c++;
274
if (w_argc>1 || cmd_line[0]!='-'||cmd_line[1]!='n'||cmd_line[2]!='o'||
275
cmd_line[3]!='m'||cmd_line[4]!='d'||cmd_line[5]!='i') {
277
w_argv = (char **)HeapReAlloc(heap, HEAP_GENERATE_EXCEPTIONS,
278
w_argv, sizeof(char *)*(2*w_argc+1));
279
w_argv[w_argc++] = mfc_cpy(heap, cmd_line, c - cmd_line);
283
if (c[0] == delim) c++;
293
mfc_cpy(HANDLE heap, const char *text, long len)
295
if (!len) while (text[len]) len++;
296
char *buf = (char *)HeapAlloc(heap, HEAP_GENERATE_EXCEPTIONS, len+1);
298
while (len--) *buf++= *text++;
306
return w_protect(mfc_run_hack);
310
mfc_worker::run_hack()
313
int (*on_launch)(int, char **)= w_on_launch;
317
int result = on_launch(w_argc, w_argv);
318
if (result) return result;
320
return CWinThread::Run();
326
return ((mfc_worker *)the_worker)->run_hack();
330
mfc_worker::PreTranslateMessage(MSG* pmsg)
332
return w_app_msg(pmsg) || CWinThread::PreTranslateMessage(pmsg);
336
mfc_worker::OnIdle(LONG count)
338
return CWinThread::OnIdle(count) || w_work_idle();
342
mfc_worker::ExitInstance()
344
w_result = w_on_quit();
345
CWinThread::ExitInstance();
346
AfxEndThread(w_result, 1); // simply returning doesn't delete the_worker
347
return w_result; // not reached
350
/*------------------------------------------------------------------------*/
355
if (!(mfc_showing&1)) {
356
CMDIFrameWnd *fw = (CMDIFrameWnd *)(the_boss.m_pMainWnd);
357
fw->ShowWindow(the_boss.m_nCmdShow);
365
mfc_term_init(void *arg)
369
if (!(mfc_showing&2)) {
370
mfc_edit_doc *doc = new mfc_edit_doc(mfc_template, 0);
371
term_view = (mfc_term_view *)doc->GetView();
372
term_view->is_visible = 1;
373
mfc_template->InitialUpdateFrame((CFrameWnd*)term_view->GetParent(),
375
doc = new mfc_edit_doc(mfc_template, 1);
376
hist_view = (mfc_term_view *)doc->GetView();
377
hist_view->is_visible = 0;
378
mfc_template->InitialUpdateFrame((CFrameWnd*)hist_view->GetParent(),
385
/*------------------------------------------------------------------------*/
387
class mfc_child : public CMDIChildWnd
389
DECLARE_DYNCREATE(mfc_child)
392
int width, height, hints;
397
virtual BOOL PreCreateWindow( CREATESTRUCT& cs );
398
virtual ~mfc_child();
400
afx_msg void OnParentNotify(UINT msg, LPARAM lp);
401
afx_msg void OnDestroy();
402
afx_msg void OnSetFocus(CWnd *w);
403
afx_msg void OnSize(UINT type, int cx, int cy);
404
afx_msg void OnMDIActivate(BOOL activate, CWnd* aw, CWnd* dw);
406
DECLARE_MESSAGE_MAP()
409
struct w_parent_args {
411
int width, height, hints;
414
static void mfc_window(struct w_parent_args *args);
417
mfc_parent(int width, int height, char *title, int hints)
420
struct w_parent_args args;
423
args.height = height;
426
the_boss.m_pMainWnd->SendMessage(ID_CALL_FUNC, (WPARAM)&args,
435
mfc_window(struct w_parent_args *args)
437
mfc_child *gw = new mfc_child;
438
gw->width = args->width;
439
gw->height = args->height;
440
gw->hints = args->hints;
442
gw->Create(0, args->title);
443
args->handle = gw->m_hWnd;
446
BEGIN_MESSAGE_MAP(mfc_child, CMDIChildWnd)
454
IMPLEMENT_DYNCREATE(mfc_child, CMDIChildWnd)
456
mfc_child::mfc_child()
461
mfc_child::~mfc_child()
466
mfc_child::PreCreateWindow(CREATESTRUCT& cs)
472
rect.right = cs.cx = width;
473
rect.bottom = cs.cy = height;
474
if (AdjustWindowRect(&rect, cs.style, 0)) {
475
cs.cx = rect.right - rect.left + 4; // is 4 really some variable?
476
cs.cy = rect.bottom - rect.top + 4;
478
if (hints & P_NORESIZE)
479
cs.style &= ~(WS_THICKFRAME | WS_MAXIMIZEBOX);
482
return CMDIChildWnd::PreCreateWindow(cs);
486
mfc_child::OnDestroy()
488
CMDIChildWnd::OnDestroy();
489
CMDIFrameWnd *fw = (CMDIFrameWnd *)the_boss.m_pMainWnd;
490
::SendMessage(fw->m_hWndMDIClient, WM_MDIREFRESHMENU, 0, 0);
494
mfc_child::OnSetFocus(CWnd *w)
496
/* first call to OnSetFocus occurs before child is created */
499
CMDIFrameWnd *fw = (CMDIFrameWnd *)the_boss.m_pMainWnd;
500
::SendMessage(fw->m_hWndMDIClient, WM_MDIREFRESHMENU, 0, 0);
504
/* apparently AttachThreadInput in mfc_worker::InitInstance unneeded? */
508
mfc_child::OnParentNotify(UINT msg, LPARAM lp)
510
if (msg==WM_CREATE) {
512
::SetFocus(child); /* mfc_child (this) already has focus */
514
CWnd::OnParentNotify(msg, lp);
518
mfc_child::OnSize(UINT type, int cx, int cy)
522
::MoveWindow(child, 0,0, r.right,r.bottom, 1);
523
CMDIChildWnd::OnSize(type, cx, cy);
527
mfc_child::OnMDIActivate(BOOL activate, CWnd* aw, CWnd* dw)
530
p_win *pw = child? (p_win *)GetWindowLong(child, GWL_USERDATA) : 0;
531
if (pw && activate && pw->palette) pw->s->active = pw;
533
CMDIChildWnd::OnMDIActivate(activate, aw, dw);
536
/*------------------------------------------------------------------------*/