//********************************************************************** // File name: app.cpp // // Implementation file for the CSimpleApp Class // // Functions: // // See app.h for a list of member functions. // // Copyright (c) 1992 - 1993 Microsoft Corporation. All rights reserved. //********************************************************************** #include "pre.h" #include "iocs.h" #include "ias.h" #include "app.h" #include "site.h" #include "doc.h" #include #ifdef WIN32 extern BOOL CALLBACK About(HWND hDlg,UINT message,WPARAM wParam,LPARAM lParam); #endif //********************************************************************** // // CSimpleApp::CSimpleApp() // // Purpose: // // Constructor for CSimpleApp // // Parameters: // // None // // Return Value: // // None // // Function Calls: // Function Location // // TestDebugOut Windows API // //******************************************************************** CSimpleApp::CSimpleApp() { TestDebugOut("In CSimpleApp's Constructor \r\n"); // Set Ref Count m_nCount = 0; // clear members m_hAppWnd = NULL; m_hInst = NULL; m_lpDoc = NULL; // clear flags m_fInitialized = FALSE; // Initialize effects we allow. m_dwSourceEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE; m_dwTargetEffect = DROPEFFECT_COPY | DROPEFFECT_MOVE; } //********************************************************************** // // CSimpleApp::~CSimpleApp() // // Purpose: // // Destructor for CSimpleApp Class. // // Parameters: // // None // // Return Value: // // None // // Function Calls: // Function Location // // OutdebugString Windows API // OleUninitialize OLE API // // //******************************************************************** CSimpleApp::~CSimpleApp() { TestDebugOut("In CSimpleApp's Destructor\r\n"); // need to uninit the library... if (m_fInitialized) OleUninitialize(); } //********************************************************************** // // CSimpleApp::DestroyDocs() // // Purpose: // // Destroys all of the open documents in the application (Only one // since this is an SDI app, but could easily be modified to // support MDI). // // Parameters: // // None // // Return Value: // // None // // Function Calls: // Function Location // // CSimpleDoc::Close DOC.CPP // //******************************************************************** void CSimpleApp::DestroyDocs() { m_lpDoc->Close(); // we have only 1 document } //********************************************************************** // // CSimpleApp::QueryInterface // // Purpose: // // Used for interface negotiation at the Application level. // // Parameters: // // REFIID riid - A reference to the interface that is // being queried. // // LPVOID FAR* ppvObj - An out parameter to return a pointer to // the interface. // // Return Value: // // S_OK - The interface is supported. // S_FALSE - The interface is not supported // // Function Calls: // Function Location // // TestDebugOut Windows API // ResultFromScode OLE API // //******************************************************************** STDMETHODIMP CSimpleApp::QueryInterface(REFIID riid, LPVOID FAR* ppvObj) { TestDebugOut("In CSimpleApp::QueryInterface\r\n"); *ppvObj = NULL; // must set out pointer parameters to NULL // Not a supported interface return ResultFromScode(E_NOINTERFACE); } //********************************************************************** // // CSimpleApp::AddRef // // Purpose: // // Adds to the reference count at the Application level. // // Parameters: // // None // // Return Value: // // ULONG - The new reference count of the application. // // Function Calls: // Function Location // // TestDebugOut Windows API // // Comments: // // Due to the reference counting model that is used in this // implementation, this reference count is the sum of the // reference counts on all interfaces of all objects open // in the application. // //******************************************************************** STDMETHODIMP_(ULONG) CSimpleApp::AddRef() { TestDebugOut("In CSimpleApp::AddRef\r\n"); return ++m_nCount; } //********************************************************************** // // CSimpleApp::Release // // Purpose: // // Decrements the reference count at the application level // // Parameters: // // None // // Return Value: // // ULONG - The new reference count of the application. // // Function Calls: // Function Location // // TestDebugOut Windows API // // //******************************************************************** STDMETHODIMP_(ULONG) CSimpleApp::Release() { TestDebugOut("In CSimpleApp::Release\r\n"); if (--m_nCount == 0) { delete this; return 0; } return m_nCount; } //********************************************************************** // // CSimpleApp::fInitApplication // // Purpose: // // Initializes the application // // Parameters: // // HANDLE hInstance - Instance handle of the application. // // Return Value: // // TRUE - Application was successfully initialized. // FALSE - Application could not be initialized // // Function Calls: // Function Location // // LoadIcon Windows API // LoadCursor Windows API // GetStockObject Windows API // RegisterClass Windows API // // //******************************************************************** BOOL CSimpleApp::fInitApplication(HANDLE hInstance) { WNDCLASS wc; // Fill in window class structure with parameters that describe the // main window. wc.style = NULL; // Class style(s). wc.lpfnWndProc = MainWndProc; // Function to retrieve messages for // windows of this class. wc.cbClsExtra = 0; // No per-class extra data. wc.cbWndExtra = 0; // No per-window extra data. wc.hInstance =(HINSTANCE) hInstance; // Application that owns // the class. wc.hIcon = LoadIcon((HINSTANCE)hInstance,TEXT("SimpDnd")); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = TEXT("SIMPLEMENU"); // Name of menu resource in // .RC file. wc.lpszClassName = TEXT("SimpDndAppWClass"); // Name used in // CreateWindow call. if (!RegisterClass(&wc)) return FALSE; wc.style = CS_DBLCLKS; // Class style(s). allow DBLCLK's wc.lpfnWndProc = DocWndProc; // Function to retrieve messages for // windows of this class. wc.cbClsExtra = 0; // No per-class extra data. wc.cbWndExtra = 0; // No per-window extra data. wc.hInstance = (HINSTANCE) hInstance; // Application that owns // the class. wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); wc.lpszMenuName = NULL; wc.lpszClassName = TEXT("SimpDndDocWClass"); // Name used in //CreateWindow call. // Register the window class and return success/failure code. return (RegisterClass(&wc)); } //********************************************************************** // // CSimpleApp::fInitInstance // // Purpose: // // Instance initialization. // // Parameters: // // HANDLE hInstance - App. Instance Handle. // // int nCmdShow - Show parameter from WinMain // // Return Value: // // TRUE - Initialization Successful // FALSE - Initialization Failed. // // // Function Calls: // Function Location // // CreateWindow Windows API // ShowWindow Windows API // UpdateWindow Windows API // GetProfileInt Windows API // OleBuildVersion OLE API // OleInitialize OLE API // OleStdCreateDbAlloc OLE2UI // // Comments: // // Note that successful Initalization of the OLE libraries // is remembered so the UnInit is only called if needed. // //******************************************************************** BOOL CSimpleApp::fInitInstance (HANDLE hInstance, int nCmdShow) { LPMALLOC lpMalloc = NULL; #ifndef WIN32 /* Since OLE is part of the operating system in Win32, we don't need to * check the version number in Win32. */ DWORD dwVer = OleBuildVersion(); // check to see if we are compatible with this version of the libraries if (HIWORD(dwVer) != rmm || LOWORD(dwVer) < rup) { #ifdef _DEBUG TestDebugOut("WARNING: Incompatible OLE library version\r\n"); #else return FALSE; #endif } #endif // WIN32 #if defined( _DEBUG ) /* OLE2NOTE: Use a special debug allocator to help track down ** memory leaks. */ OleStdCreateDbAlloc(0, &lpMalloc); #endif // We try passing in our own allocator first - if that fails we // try without overriding the allocator. if (SUCCEEDED(OleInitialize(lpMalloc)) || SUCCEEDED(OleInitialize(NULL))) { m_fInitialized = TRUE; } #if defined( _DEBUG ) /* OLE2NOTE: release the special debug allocator so that only OLE is ** holding on to it. later when OleUninitialize is called, then ** the debug allocator object will be destroyed. when the debug ** allocator object is destoyed, it will report (to the Output ** Debug Terminal) whether there are any memory leaks. */ if (lpMalloc) lpMalloc->Release(); #endif m_hInst = (HINSTANCE) hInstance; // Create the "application" windows m_hAppWnd = CreateWindow (TEXT("SimpDndAppWClass"), TEXT("Simple OLE 2.0 Drag/Drop Container"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, (HINSTANCE) hInstance, NULL); if (!m_hAppWnd) return FALSE; // if we have been launched by the test driver, tell it our window handle if( m_hDriverWnd ) { PostMessage(m_hDriverWnd, WM_TESTREG, (WPARAM)m_hAppWnd, 0); } // delay before dragging should start, in milliseconds m_nDragDelay = GetProfileInt( TEXT("windows"), TEXT("DragDelay"), DD_DEFDRAGDELAY ); // minimum distance (radius) before drag should start, in pixels m_nDragMinDist = GetProfileInt( TEXT("windows"), TEXT("DragMinDist"), DD_DEFDRAGMINDIST ); // delay before scrolling, in milliseconds m_nScrollDelay = GetProfileInt( TEXT("windows"), TEXT("DragScrollDelay"), DD_DEFSCROLLDELAY ); // inset-width of the hot zone, in pixels m_nScrollInset = GetProfileInt( TEXT("windows"), TEXT("DragScrollInset"), DD_DEFSCROLLINSET ); // scroll interval, in milliseconds m_nScrollInterval = GetProfileInt( TEXT("windows"), TEXT("DragScrollInterval"), DD_DEFSCROLLINTERVAL ); ShowWindow (m_hAppWnd, nCmdShow); UpdateWindow (m_hAppWnd); return m_fInitialized; } //+------------------------------------------------------------------------- // // Member: CSimpleApp::UpdateDragDropEffects // // Synopsis: Update drag/drop effects // // Arguments: [iMenuPos] - menu position either source or target // [iMenuCommand] - what command the menu selection maps to // [dwEffect] - new effects // [pdwEffectToUpdate] - where to store the effects // // Algorithm: Get the menu for either source or target. Then clear any // outstanding check marks. Check the appropriate item. Finally // update the effects that we allow. // // History: dd-mmm-yy Author Comment // 06-May-94 Ricksa author // //-------------------------------------------------------------------------- void CSimpleApp::UpdateDragDropEffects( int iMenuPos, int iMenuCommand, DWORD dwEffect, DWORD *pdwEffectToUpdate) { // Get the menu that we want to process HMENU hMenuItem = GetSubMenu(m_hHelpMenu, iMenuPos); // Clear any current check marks for (int i = 0; i < 3; i++) { CheckMenuItem(hMenuItem, i, MF_BYPOSITION | MF_UNCHECKED); } // Check the appropriate item. CheckMenuItem(hMenuItem, iMenuCommand, MF_BYCOMMAND | MF_CHECKED); *pdwEffectToUpdate = dwEffect; } //********************************************************************** // // CSimpleApp::lCommandHandler // // Purpose: // // Handles the processing of WM_COMMAND. // // Parameters: // // HWND hWnd - Handle to the application Window // // UINT message - message (always WM_COMMAND) // // WPARAM wParam - Same as passed to the WndProc // // LPARAM lParam - Same as passed to the WndProc // // Return Value: // // NULL // // Function Calls: // Function Location // // IOleObject::DoVerb Object // GetClientRect Windows API // MessageBox Windows API // DialogBox Windows API // MakeProcInstance Windows API // FreeProcInstance Windows API // SendMessage Windows API // DefWindowProc Windows API // CSimpleDoc::InsertObject DOC.CPP // CSimpleDoc::CopyObjectToClip DOC.CPP // CSimpleDoc::Close DOC.CPP // //******************************************************************** long CSimpleApp::lCommandHandler (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT rect; // see if the command is a verb selections if (wParam >= IDM_VERB0) { // get the rectangle of the object m_lpDoc->m_lpSite->GetObjRect(&rect); if (m_lpDoc->m_lpSite->m_lpOleObject->DoVerb( wParam - IDM_VERB0, NULL, &m_lpDoc->m_lpSite->m_OleClientSite, -1, m_lpDoc->m_hDocWnd, &rect) != ResultFromScode(S_OK)) { TestDebugOut("Fail in IOleObject::DoVerb\n"); } } else { switch (wParam) { // bring up the About box case IDM_ABOUT: { #ifdef WIN32 DialogBox(m_hInst, // current instance TEXT("AboutBox"), // resource to use m_hAppWnd, // parent handle About); // About() instance address #else FARPROC lpProcAbout = MakeProcInstance((FARPROC)About, m_hInst); DialogBox(m_hInst, // current instance TEXT("AboutBox"), // resource to use m_hAppWnd, // parent handle lpProcAbout); // About() instance address FreeProcInstance(lpProcAbout); #endif break; } // bring up the InsertObject Dialog case IDM_INSERTOBJECT: m_lpDoc->InsertObject(); break; // Copy the object to the Clipboard case IDM_COPY: m_lpDoc->CopyObjectToClip(); break; // exit the application case IDM_EXIT: SendMessage(hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L); break; case IDM_NEW: lCreateDoc(hWnd, 0, 0, 0); break; // Only allow copy from the source case IDM_SOURCE_COPY: UpdateDragDropEffects(SOURCE_EFFECTS_MENU_POS, IDM_SOURCE_COPY, DROPEFFECT_COPY, &m_dwSourceEffect); break; // Only allow move from the source case IDM_SOURCE_MOVE: UpdateDragDropEffects(SOURCE_EFFECTS_MENU_POS, IDM_SOURCE_MOVE, DROPEFFECT_MOVE, &m_dwSourceEffect); break; // Allow both copy and move from the source case IDM_SOURCE_COPYMOVE: UpdateDragDropEffects(SOURCE_EFFECTS_MENU_POS, IDM_SOURCE_COPYMOVE, DROPEFFECT_COPY | DROPEFFECT_MOVE, &m_dwSourceEffect); break; // Only accept copy in target case IDM_TARGET_COPY: UpdateDragDropEffects(TARGET_EFFECTS_MENU_POS, IDM_TARGET_COPY, DROPEFFECT_COPY, &m_dwTargetEffect); break; // Only accept move in target case IDM_TARGET_MOVE: UpdateDragDropEffects(TARGET_EFFECTS_MENU_POS, IDM_TARGET_MOVE, DROPEFFECT_MOVE, &m_dwTargetEffect); break; // Accept both move and copy in the target case IDM_TARGET_COPYMOVE: UpdateDragDropEffects(TARGET_EFFECTS_MENU_POS, IDM_TARGET_COPYMOVE, DROPEFFECT_COPY | DROPEFFECT_MOVE, &m_dwTargetEffect); break; default: return (DefWindowProc(hWnd, message, wParam, lParam)); } // end of switch } // end of else return NULL; } //********************************************************************** // // CSimpleApp::lSizeHandler // // Purpose: // // Handles the WM_SIZE message // // Parameters: // // HWND hWnd - Handle to the application Window // // UINT message - message (always WM_SIZE) // // WPARAM wParam - Same as passed to the WndProc // // LPARAM lParam - Same as passed to the WndProc // // Return Value: // // LONG - returned from the "document" resizing // // Function Calls: // Function Location // // GetClientRect Windows API // CSimpleDoc::lResizeDoc DOC.CPP // // //******************************************************************** long CSimpleApp::lSizeHandler (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT rect; GetClientRect(m_hAppWnd, &rect); return m_lpDoc->lResizeDoc(&rect); } //********************************************************************** // // CSimpleApp::lCreateDoc // // Purpose: // // Handles the creation of a document object. // // Parameters: // // HWND hWnd - Handle to the application Window // // UINT message - message (always WM_CREATE) // // WPARAM wParam - Same as passed to the WndProc // // LPARAM lParam - Same as passed to the WndProc // // Return Value: // // NULL // // Function Calls: // Function Location // // GetClientRect Windows API // CSimpleDoc::CSimpleDoc DOC.CPP // // //******************************************************************** long CSimpleApp::lCreateDoc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT rect; static BOOL fFirstTime = TRUE; if (m_lpDoc != NULL) { // There is a document defined already so we close it without // saving which is equivalent to deleting the object. m_lpDoc->Close(); m_lpDoc = NULL; } GetClientRect(hWnd, &rect); m_lpDoc = CSimpleDoc::Create(this, &rect, hWnd); // First time initialization - for some reason the doc sets the // the application's m_hHelpMenu which we need. So we do the // initialization here. if (fFirstTime) { fFirstTime = FALSE; // Check default allowed effects for the source UpdateDragDropEffects(SOURCE_EFFECTS_MENU_POS, IDM_SOURCE_COPYMOVE, m_dwSourceEffect, &m_dwSourceEffect); // Check default allowed effects for the target UpdateDragDropEffects(TARGET_EFFECTS_MENU_POS, IDM_TARGET_COPYMOVE, m_dwTargetEffect, &m_dwTargetEffect); } return NULL; } //********************************************************************** // // CSimpleApp::HandleAccelerators // // Purpose: // // To properly handle accelerators in the Message Loop // // Parameters: // // LPMSG lpMsg - A pointer to the message structure. // // Return Value: // // TRUE - The accelerator was handled // FALSE - The accelerator was not handled // // Function Calls: // Function Location // // //******************************************************************** BOOL CSimpleApp::HandleAccelerators(LPMSG lpMsg) { BOOL retval = FALSE; // we do not have any accelerators return retval; } //********************************************************************** // // CSimpleApp::PaintApp // // Purpose: // // Handles the painting of the doc window. // // // Parameters: // // HDC hDC - hDC to the Doc Window. // // Return Value: // // None // // Function Calls: // Function Location // // CSimpleDoc::PaintDoc DOC.CPP // // Comments: // // This is an app level function in case we want to do palette // management. // //******************************************************************** void CSimpleApp::PaintApp (HDC hDC) { // at this level, we could enumerate through all of the // visible objects in the application, so that a palette // that best fits all of the objects can be built. // This app is designed to take on the same palette // functionality that was provided in OLE 1.0, the palette // of the last object drawn is realized. Since we only // support one object at a time, it shouldn't be a big // deal. // if we supported multiple documents, we would enumerate // through each of the open documents and call paint. if (m_lpDoc) { m_lpDoc->PaintDoc(hDC); } }