/******************************************************************************* * * (C) COPYRIGHT MICROSOFT CORPORATION, 1998-2001 * * TITLE: STIEVENT.CPP * * VERSION: 1.0 * * AUTHOR: ShaunIv * * DATE: 4-6-2001 * * DESCRIPTION: * *******************************************************************************/ #include "precomp.h" #pragma hdrstop #include #include "simcrack.h" #include "resource.h" #include "stievent.h" #include "evntparm.h" #include "shmemsec.h" // // This dialog displays the sti application list and lets the user choose one. // class CStiEventHandlerDialog { public: struct CData { // // This will contain the event information, including the application list, // which is really what we are interested in. // CStiEventData *pStiEventData; // // The OUT member is intended to contain the selected handler, which will // be copied from the list contained in the CStiEventData class // CStiEventData::CStiEventHandler EventHandler; // // We will set the window handle in this shared memory section, // so we can activate ourselves. // CSharedMemorySection *pStiEventHandlerSharedMemory; }; private: // // Not implemented // CStiEventHandlerDialog(); CStiEventHandlerDialog( const CStiEventHandlerDialog & ); CStiEventHandlerDialog &operator=( const CStiEventHandlerDialog & ); private: HWND m_hWnd; CData *m_pData; private: // // Sole constructor // explicit CStiEventHandlerDialog( HWND hWnd ) : m_hWnd(hWnd), m_pData(NULL) { } // // Destructor // ~CStiEventHandlerDialog() { m_hWnd = NULL; m_pData = NULL; } // // WM_INITDIALOG handler. // LRESULT OnInitDialog( WPARAM, LPARAM lParam ) { // // Get the dialog's data // m_pData = reinterpret_cast(lParam); // // Make sure we have valid data // if (!m_pData || !m_pData->pStiEventData) { EndDialog( m_hWnd, -1 ); SetLastError( ERROR_INVALID_PARAMETER ); return 0; } // // Make sure we were supplied with a memory section // if (m_pData->pStiEventHandlerSharedMemory) { // // Get a pointer to the shared memory // HWND *phWnd = m_pData->pStiEventHandlerSharedMemory->Lock(); if (phWnd) { // // Store our window handle // *phWnd = m_hWnd; // // Release the mutex // m_pData->pStiEventHandlerSharedMemory->Release(); } } // // Add the handlers to the list // for (int i=0;ipStiEventData->EventHandlers().Size();++i) { // // Get the program name and make sure it is valid // CSimpleString strAppName = CSimpleStringConvert::NaturalString(m_pData->pStiEventData->EventHandlers()[i].ApplicationName()); if (strAppName.Length()) { // // Add the string and save the item id // LRESULT nIndex = SendDlgItemMessage( m_hWnd, IDC_STI_APPS_LIST, LB_ADDSTRING, 0, reinterpret_cast(strAppName.String()) ); if (LB_ERR != nIndex) { // // Set the item data to the index in our handler array // SendDlgItemMessage( m_hWnd, IDC_STI_APPS_LIST, LB_SETITEMDATA, nIndex, i ); } } } // // Select the first item // SendDlgItemMessage( m_hWnd, IDC_STI_APPS_LIST, LB_SETCURSEL, 0, 0 ); // // Enable the OK button if we have a valid selected item // EnableWindow( GetDlgItem( m_hWnd, IDOK ), GetHandlerIndexOfCurrentSelection() != -1 ); return 0; } void OnCancel( WPARAM, LPARAM ) { // // Just close the dialog on cancel // EndDialog( m_hWnd, IDCANCEL ); } int GetHandlerIndexOfCurrentSelection() { // // Assume failure // int nResult = -1; // // Make sure we have valid pointers still // if (m_pData && m_pData->pStiEventData) { // // Get the current selection index and make sure it is valid // LRESULT nCurIndex = SendDlgItemMessage( m_hWnd, IDC_STI_APPS_LIST, LB_GETCURSEL, 0, 0 ); if (LB_ERR != nCurIndex) { // // Get the index into our event handler array from the item data for the current item // LRESULT nEventItemIndex = SendDlgItemMessage( m_hWnd, IDC_STI_APPS_LIST, LB_GETITEMDATA, nCurIndex, 0 ); // // Make sure the index is valid // if (nEventItemIndex >= 0 && nEventItemIndex < m_pData->pStiEventData->EventHandlers().Size()) { nResult = static_cast(nEventItemIndex); } } } return nResult; } void OnOK( WPARAM, LPARAM ) { // // Make sure we have valid parameters // int nEventItemIndex = GetHandlerIndexOfCurrentSelection(); if (-1 != nEventItemIndex) { // // Copy the event handler to our OUT parameter // m_pData->EventHandler = m_pData->pStiEventData->EventHandlers()[nEventItemIndex]; // // Close the dialog // EndDialog( m_hWnd, IDOK ); } } void OnAppsListDblClk( WPARAM, LPARAM ) { // // Simulate the user pressing the OK button // SendMessage( m_hWnd, WM_COMMAND, MAKEWPARAM(IDOK,0), 0 ); } void OnAppsListSelChange( WPARAM, LPARAM ) { // // Enable the OK button if we have a valid selected item // EnableWindow( GetDlgItem( m_hWnd, IDOK ), GetHandlerIndexOfCurrentSelection() != -1 ); } LRESULT OnCommand( WPARAM wParam, LPARAM lParam ) { SC_BEGIN_COMMAND_HANDLERS() { SC_HANDLE_COMMAND(IDCANCEL,OnCancel); SC_HANDLE_COMMAND(IDOK,OnOK); SC_HANDLE_COMMAND_NOTIFY(LBN_DBLCLK,IDC_STI_APPS_LIST,OnAppsListDblClk); SC_HANDLE_COMMAND_NOTIFY(LBN_SELCHANGE,IDC_STI_APPS_LIST,OnAppsListSelChange); } SC_END_COMMAND_HANDLERS(); } public: static INT_PTR __stdcall DlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { SC_BEGIN_DIALOG_MESSAGE_HANDLERS(CStiEventHandlerDialog) { SC_HANDLE_DIALOG_MESSAGE( WM_INITDIALOG, OnInitDialog ); SC_HANDLE_DIALOG_MESSAGE( WM_COMMAND, OnCommand ); } SC_END_DIALOG_MESSAGE_HANDLERS(); } }; HRESULT StiEventHandler( CStiEventData &StiEventData ) { HRESULT hr = S_OK; #if defined(DBG) // // Dump the parameters // WIA_PUSH_FUNCTION((TEXT("StiEventHandler"))); WIA_PRINTGUID((StiEventData.Event(),TEXT(" Event"))); WIA_TRACE((TEXT(" EventDescription: %ws"), StiEventData.EventDescription().String())); WIA_TRACE((TEXT(" DeviceDescription: %ws"), StiEventData.DeviceDescription().String())); WIA_TRACE((TEXT(" DeviceId: %ws"), StiEventData.DeviceId().String())); WIA_TRACE((TEXT(" EventType: %08X"), StiEventData.EventType())); WIA_TRACE((TEXT(" Reserved: %08X"), StiEventData.Reserved())); for (int i=0;i StiEventHandlerSharedMemory; // // If we were able to open the memory section // if (CSharedMemorySection::SmsOpened == StiEventHandlerSharedMemory.Open( CSimpleStringConvert::NaturalString(CSimpleStringWide(strMutexName)), true )) { HWND *phWnd = StiEventHandlerSharedMemory.Lock(); if (phWnd) { // // Make sure we have a valid window handle // if (*phWnd && IsWindow(*phWnd)) { // // If it is a valid window, bring it to the foreground. // SetForegroundWindow(*phWnd); } // // Release the mutex // StiEventHandlerSharedMemory.Release(); } } else { // // We will execute this handler below, after we decide which one to use // CStiEventData::CStiEventHandler EventHandler; // // If there is only one handler, save that handler // if (1 == StiEventData.EventHandlers().Size()) { EventHandler = StiEventData.EventHandlers()[0]; } // // Otherwise, if there is more than one handler, display the handler prompt dialog // else { // // Prepare the dialog data // CStiEventHandlerDialog::CData DialogData; DialogData.pStiEventData = &StiEventData; DialogData.pStiEventHandlerSharedMemory = &StiEventHandlerSharedMemory; // // Display the dialog // INT_PTR nDialogResult = DialogBoxParam( g_hInstance, MAKEINTRESOURCE(IDD_CHOOSE_STI_APPLICATION), NULL, CStiEventHandlerDialog::DlgProc, reinterpret_cast(&DialogData) ); // // If the user selected a program and hit OK, save the handler // if (IDOK == nDialogResult) { EventHandler = DialogData.EventHandler; } // // If the user cancelled, just return S_FALSE immediately (premature return) // else if (IDCANCEL == nDialogResult) { return S_FALSE; } // // If there was an internal error, save the correct error // else if (-1 == nDialogResult) { hr = HRESULT_FROM_WIN32(GetLastError()); } // // For all other return values, save a generic error // else { hr = E_FAIL; } } if (SUCCEEDED(hr)) { // // Make sure we have a valid handler // if (EventHandler.IsValid()) { // // Prepare the process information // STARTUPINFO StartupInfo = {0}; StartupInfo.cb = sizeof(StartupInfo); // // Convert the command line to a TCHAR string // CSimpleString CommandLine = CSimpleStringConvert::NaturalString(EventHandler.CommandLine()); // // Make sure we actually have a command line // if (CommandLine.Length()) { // // Execute the program // PROCESS_INFORMATION ProcessInformation = {0}; if (CreateProcess( NULL, const_cast(CommandLine.String()), NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInformation )) { // // If the program succeeded, close the handles to prevent leaks // CloseHandle( ProcessInformation.hProcess ); CloseHandle( ProcessInformation.hThread ); } else { // // Save the error from CreateProcess // hr = HRESULT_FROM_WIN32(GetLastError()); } } else { // // Assume out of memory error if we couldn't create the string // hr = E_OUTOFMEMORY; } } else { // // Who knows what went wrong? // hr = E_FAIL; } } // // If we've failed, display an error message // if (FAILED(hr)) { // // We will display this string, after we've constructed it // CSimpleString strMessage; // // Get the error text // CSimpleString strError = WiaUiUtil::GetErrorTextFromHResult(hr); // // Get the application name // CSimpleString strApplication = CSimpleStringConvert::NaturalString(EventHandler.ApplicationName()); // // If we don't have an application name, use some default // if (!strApplication.Length()) { strApplication.LoadString( IDS_STI_EVENT_ERROR_APP_NAME, g_hInstance ); } // // If we have a specific error message, use it. // if (strError.Length()) { strMessage.Format( IDS_STI_EVENT_ERROR_WITH_EXPLANATION, g_hInstance, strApplication.String(), strError.String() ); } // // Otherwise, use a generic error message. // else { strMessage.Format( IDS_STI_EVENT_ERROR_NO_EXPLANATION, g_hInstance, strApplication.String() ); } // // Display the error message. // MessageBox( NULL, strMessage, CSimpleString( IDS_STI_EVENT_ERROR_TITLE, g_hInstance ), MB_ICONHAND ); } } // // We're done here // return hr; }