/* * i n i t . c p p * * Purpose: * * History * * Copyright (C) Microsoft Corp. 1995, 1996. */ #include #include "dllmain.h" #include "msoert.h" #include "mimeole.h" #include "envhost.h" #include "init.h" LRESULT CALLBACK InitWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); HRESULT HrCreateNoteThisThread(WPARAM wp, LPARAM lp); DWORD MainThreadProc(LPVOID lpvUnused); void NoteMsgPump(); CGWNote *g_pActiveNote=0; HWND g_hwndInit = NULL; HEVENT g_hEventSpoolerInit =NULL; DWORD g_dwNoteThreadID=0; BOOL g_fInitialized=FALSE; static HTHREAD s_hMainThread = NULL; static HEVENT s_hInitEvent = NULL; static DWORD s_dwMainThreadId = 0; static TCHAR s_szInitWndClass[] = "GWInitWindow"; void InitGWNoteThread(BOOL fInit) { if (fInit) { // create an event for the main thread to signal if (s_hInitEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) { if (s_hMainThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MainThreadProc, NULL, 0, &s_dwMainThreadId)) { HANDLE rghWait[]={s_hMainThread, s_hInitEvent}; // wait for the main thread to signal that initialization is complete WaitForMultipleObjects(sizeof(rghWait)/sizeof(HANDLE), rghWait, FALSE, INFINITE); } CloseHandle(s_hInitEvent); s_hInitEvent = NULL; } } else { // tell the main thread to deinitialize everything // the SendMessage() will block the calling thread until deinit is complete, if (g_hwndInit) SendMessage(g_hwndInit, ITM_SHUTDOWNTHREAD, 0, 0); // wait for main thread to terminate (when it exits its message loop) // this isn't strictly necessary, but it helps to ensure proper cleanup. WaitForSingleObject(s_hMainThread, INFINITE); CloseHandle(s_hMainThread); s_hMainThread = NULL; } } DWORD MainThreadProc(LPVOID lpvUnused) { DWORD dw; HRESULT hr; RECT rc={0}; WNDCLASS wc = { 0, // style InitWndProc, // lpfnWndProc 0, // cbClsExtra 0, // cbWndExtra g_hInst, // hInstance NULL, // hIcon NULL, // hCursor NULL, // hbrBackground NULL, // lpszMenuName s_szInitWndClass }; // lpszClassName g_dwNoteThreadID = GetCurrentThreadId(); if (!RegisterClass(&wc)) return 0; g_hwndInit = CreateWindowEx(NULL, s_szInitWndClass, s_szInitWndClass, WS_POPUP, 0,0,0,0, NULL, NULL, g_hInst, NULL); if (!g_hwndInit) return 0; OleInitialize(0); g_fInitialized=TRUE; SetEvent(s_hInitEvent); NoteMsgPump(); return 0; } LRESULT CALLBACK InitWndProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) { BOOL fRet; HRESULT hr; switch(msg) { case ITM_SHUTDOWNTHREAD: Assert(GetCurrentThreadId()==s_dwMainThreadId); OleUninitialize(); DestroyWindow(hwnd); PostThreadMessage(s_dwMainThreadId, WM_QUIT, 0, 0); g_fInitialized=FALSE; return 0; case ITM_CREATENOTEONTHREAD: return (LONG)HrCreateNoteThisThread(wp, lp); } return DefWindowProc(hwnd, msg, wp, lp); } void NoteMsgPump() { MSG msg; while (GetMessage(&msg, NULL, 0, 0)) { if (msg.hwnd != g_hwndInit && // ignore init window msgs IsWindow(msg.hwnd)) // ignore per-task msgs where hwnd=0 { if(g_pActiveNote && // if a note has focus, call it's XLateAccelerator... g_pActiveNote->TranslateAcclerator(&msg)==S_OK) continue; } TranslateMessage(&msg); DispatchMessage(&msg); } } HRESULT HrCreateNote(REFCLSID clsidEnvelope, DWORD dwFlags) { LPOLESTR pstr; HRESULT hr; if (FAILED(StringFromCLSID(clsidEnvelope, &pstr))) return E_FAIL; // switch thread hr = SendMessage (g_hwndInit, ITM_CREATENOTEONTHREAD, (WPARAM)pstr, (LPARAM)dwFlags); CoTaskMemFree(pstr); return hr; } HRESULT HrCreateNoteThisThread(WPARAM wp, LPARAM lp) { static HINSTANCE s_hRichEdit=0; HRESULT hr; CGWNote *pNote=0; CLSID clsid; // hack, need to free lib this if (!s_hRichEdit) s_hRichEdit = LoadLibrary("RICHED32.DLL"); // need to create this puppy on new thread pNote = new CGWNote(NULL); if (!pNote) return E_OUTOFMEMORY; CLSIDFromString((LPOLESTR)wp, &clsid); hr = pNote->Init(clsid, (DWORD)lp); if (FAILED(hr)) goto error; hr = pNote->Show(); error: ReleaseObj(pNote); return hr; }