Отправляет email-рассылки с помощью сервиса Sendsay

Школа программирования

  Все выпуски  

Школа программирования Проще...:)


В прошлый раз я немного намудрил с передачей вызова:))) Тот метод, который я описал в тот раз, я использую в сервисах, где в общем-то нет окон. Но здесь можно поступить проще - передать оконное сообщение WM_COPYDATA. Чтобы передать сообщение добавим указатель на DLG_SPLASH в объявление класса CDocumentEventSinkNotify и изменим конструктор.

class CDocumentEventSinkNotify : public CCmdTarget
{
    CWnd *m_wnd_ptr;
// Attributes
public:
   
    CDocumentEventSinkNotify(CWnd *_wnd_ptr);
    virtual ~CDocumentEventSinkNotify();

// Operations
public:

// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CDocumentEventSinkNotify)
    //}}AFX_VIRTUAL

// Implementation
protected:


    void DocumentComplete(LPDISPATCH pDisp, VARIANT FAR* URL);
    // Generated message map functions
    //{{AFX_MSG(CDocumentEventSinkNotify)
        // NOTE - the ClassWizard will add and remove member functions here.
    //}}AFX_MSG

    DECLARE_MESSAGE_MAP()
    DECLARE_DISPATCH_MAP()
};

     Изменим реализацию конструктора
CDocumentEventSinkNotify::CDocumentEventSinkNotify(CWnd *_wnd_ptr)
{
    EnableAutomation();
    m_wnd_ptr = _wnd_ptr;
}

     Теперь класс
DLG_SPLASH будет выглядеть так:

class DLG_SPLASH : public CDialog
{
private:
.....
    CDocumentEventSinkNotify m_document_notify_sink;
.....
};   

     А метод
DocumentComplete так:

void CDocumentEventSinkNotify::DocumentComplete(LPDISPATCH pDisp, VARIANT FAR* URL)
{
    COPYDATASTRUCT cd;
    cd.lpData=0;
    cd.cbData=0;
   
    HWND _wnd = m_wnd_ptr->GetSafeHwnd();
    if (IsWindow(_wnd))
    {
        ::SendMessage(_wnd,WM_COPYDATA, 0, (LPARAM) &cd);
    }

}

     Теперь надо получить это сообщение:)) С помощью визарда сгенерим код

10_1

10_2

      Получим

BOOL DLG_SPLASH::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
    if ((pCopyDataStruct->lpData == 0) && (pCopyDataStruct->cbData == 0))
        OnDocumentComplete();
   
    return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}


     Второй момент на сегодня - это код, который позволит запускать нашу программу сразу после запуска операционной системы. Для этого нужно прописать в реестр по адресу HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run  ключ с любым именем (например именем нашей программы) и сделать значением этого ключа путь к нашей программе

CString CWaterEyeKeeperDlg::GetFileName()
{
    TCHAR sFilename[_MAX_PATH];
    TCHAR sDrive[_MAX_DRIVE];
    TCHAR sDir[_MAX_DIR];
    TCHAR sFname[_MAX_FNAME];
    TCHAR sExt[_MAX_EXT];
   
    GetModuleFileName(NULL, sFilename, _MAX_PATH);
    _tsplitpath(sFilename, sDrive, sDir, sFname, sExt);
   
   
    return sFname;
}
//--------------------------------------------------------------------------
CString CWaterEyeKeeperDlg::GetFileFullName()
{
    TCHAR sFilename[_MAX_PATH];
    GetModuleFileName(NULL, sFilename, _MAX_PATH);
    return sFilename;
}

//-----------------------------------------------------------------------------
void CWaterEyeKeeperDlg::SetAutoRun(bool _run)
{
    if (_run == true)
        PutValueToRegistry(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run", GetFileName(), GetFileFullName());
    else
        DeleteKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run", GetFileName());
}
//-----------------------------------------------------------------------------

bool CWaterEyeKeeperDlg::IsAutoRun()
{
    CString temp;
    return     GetValueFromRegistry(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run", GetFileName(), temp);
}
//--------------------------------------------------------------------------

bool CWaterEyeKeeperDlg::PutValueToRegistry(HKEY root_key, LPCSTR l_strExampleKey, LPCSTR Key_Name, LPCSTR Key_Val)
{

    HKEY hKey;
    DWORD dwDisp = 0;
    LPDWORD lpdwDisp = &dwDisp;
    LONG iSuccess = RegCreateKeyEx( root_key, l_strExampleKey, 0L,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey,lpdwDisp);
    bool er = false;
   
    if(iSuccess == ERROR_SUCCESS)
    {
        if (RegSetValueEx(hKey, Key_Name, 0, REG_SZ, (LPBYTE)Key_Val, strlen(Key_Val) + 1)==ERROR_SUCCESS) er = true;
       
        ::RegCloseKey(hKey);
    }
   
    return er;

}
//-----------------------------------------------------------------------------
bool CWaterEyeKeeperDlg::GetValueFromRegistry(HKEY root_key, LPCSTR l_strExampleKey, LPCSTR Key_Name, CString &Key_Val)
{
    HKEY hKey;
    DWORD dwDisp = 0;
    LPDWORD lpdwDisp = &dwDisp;
    CString l_strStringSampleVal;
    //    DWORD dwVal;
    LONG iSuccess = RegCreateKeyEx( root_key, l_strExampleKey, 0L,NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey,lpdwDisp);
    DWORD dwType, dwCount;
   
    bool er = false;
    CString sValue;
    if(iSuccess == ERROR_SUCCESS)
    {
        if(RegQueryValueEx(hKey, Key_Name, 0, &dwType, NULL, &dwCount)!=ERROR_SUCCESS) er = false;
       
        if (dwType!=REG_SZ) er = false;
       
        if (RegQueryValueEx(hKey, Key_Name,
            NULL, &dwType, (LPBYTE)sValue.GetBuffer(dwCount/sizeof(TCHAR)),
            &dwCount) == ERROR_SUCCESS) er = true;
       
        if (er==true)
            Key_Val = sValue;
        else Key_Val = "";
       
        RegCloseKey(hKey);
    }
   
    return er;
}
//-----------------------------------------------------------------------------
bool CWaterEyeKeeperDlg::DeleteKey(HKEY hKeyParent, LPCSTR lpszKeyChild, LPCSTR lpszKeyName)
{
    bool ret_val = false;
    HKEY hKey;
    if(::RegOpenKeyEx(hKeyParent, lpszKeyChild, 0L, KEY_ALL_ACCESS, &hKey)==ERROR_SUCCESS)
        ret_val = ::RegDeleteValue(hKey, lpszKeyName);
    ::RegCloseKey(hKey);
   
    return ret_val;
}
//-----------------------------------------------------------------------------

     Немного изменим код загрузки и сохранения параметров.

void CWaterEyeKeeperDlg::LoadSettings()
{
     CString _path = GetFilePath() + ".ini";
   
    if (ReadFromIniFile(_path,"Settings","MinutesDelayBetweenRest", m_minutes_delay_between_rest)==false)
        m_minutes_delay_between_rest = 50;

    if (ReadFromIniFile(_path,"Settings","MinutesRestTime", m_minutes_rest_time)==false)
        m_minutes_rest_time = 10;

   
    m_load_on_start = IsAutoRun();
       

    m_dlg_minutes_delay_between_rest = m_minutes_delay_between_rest;
    m_dlg_minutes_rest_time = m_minutes_rest_time;
    m_dlg_load_on_start = m_load_on_start;

        UpdateData(false);
}
//--------------------------------------------------------------------------
void CWaterEyeKeeperDlg::SaveSettings()
{
   
    UpdateData(true);
   
    m_minutes_delay_between_rest = m_dlg_minutes_delay_between_rest;
    m_minutes_rest_time = m_dlg_minutes_rest_time;
    m_load_on_start = m_dlg_load_on_start?true:false;

   
    CString _path = GetFilePath() + ".ini";
   
    WriteToIniFile(_path,"Settings","MinutesDelayBetweenRest", m_minutes_delay_between_rest);
    WriteToIniFile(_path,"Settings","MinutesRestTime", m_minutes_rest_time);
   
    SetAutoRun(m_load_on_start);
    
}

     Ну и напоследок пару моментов:) Некоторые люди используют клавиатуру при переходе от одного элемента в окне к другому - так получается быстрее, чем мышкой. Поэтому нужно выставить порядок перехода от одного элемента к другому по нажатию клавиши Tab.

10_3

Если порядок не такой, то надо пройтись мышкой в нужной последовательности по элементам.

10_4

И сделать клавишу Применить нажатой по умолчанию

10_5

10_6

      На сегодня все:) Скачать исходники можно отсюда - http://program-school.narod.ru/source/waterEyeKeeper4.zip До встречи:)

В избранное