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

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

  Все выпуски  

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


Конструктивная критика.

     Не знаю как Вас, но меня критика бывает раздражает, а бывает, что нет. И раздражает как раз неконструктивная критика. Чем отличается конструктивная критика от неконструктивной. Это очень просто: когда Вам говорят, что это не так, это плохо, увидят вот это, у меня появилось чувство, что...и т.д. в том же духе, без объяснения, а что нужно сделать, для того, чтобы было правильно - это классическая неконструктивная критика. Толку от нее никакого, зато вред есть, если принять близко к сердцу. И ведь обратите внимание, когда есть неконструктивная критика, обсуждения неизвестно чего длятся очень долго и ничем не заканчиваются. Вы можете задать в конце вопрос: что в сухом остатке? - и не получить никакого ответа. Это например очень часто касается дизайна:)) А вот когда критика конструктивная, то обычно всем все понятно - понятно, что делать, и обсуждения длятся очень недолго.

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

Запустим таймер. В классе объявим новую переменную m_timer

class CWaterEyeKeeperDlg : public CDialog
{
private:
    int m_timer;
...

    int m_sec_count;

    DLG_SPLASH m_dlg_splash;
}


А в OnInitDialog() собственно его запустим

BOOL CWaterEyeKeeperDlg::OnInitDialog()
{
    CDialog::OnInitDialog();
    .....
    m_sec_count = 0;
    m_timer = SetTimer(1,1000,0);
}

Обрабатывать тики таймера мы будем в методе OnTimer. Т.к. таймер один, то не будем проверять nIDEvent.

void CWaterEyeKeeperDlg::OnTimer(UINT nIDEvent)
{
    m_sec_count++;

    if (m_dlg_splash.IsWindowVisible() == false)
    {
        if (m_sec_count > m_minutes_delay_between_rest * 60)
        {
            m_dlg_splash.SplashShow();
            m_show_splash = true;
            m_sec_count = 0;
        }
    }
    else
    {
        if (m_sec_count > m_minutes_rest_time * 60)
        {
            m_dlg_splash.SplashHide();
            m_show_splash = false;
            m_sec_count = 0;
        }

    }

   
    CDialog::OnTimer(nIDEvent);
}

      Когда срабатывает таймер, а срабатывает он каждую секунду, мы увеличиваем счетчик. Далее смотрим открыт ли наш диалог перерыва. Если закрыт и значение счетчика больше, чем время между перерывами, то показываем диалог перерыва. Если же он открыт, то проверяем счетчик, а не превышает ли его значение времени перерыва. Если превышает - закрываем диалог перерыва.

     Для того, чтобы наш диалог перерыва все время был на самом виду используем SetWindowPos с флагом HWND_TOPMOST, а чтобы окно занимало много пространства изменим его размеры, так чтобы он занимал 90% экрана

BOOL DLG_SPLASH::OnInitDialog()
{
    CDialog::OnInitDialog();
   
    CRect m_rect;
    GetClientRect(&m_rect);

    if (m_wnd_browser.CreateControl(__uuidof(WebBrowser),"Browser", WS_VISIBLE,
        m_rect,this,65000) == TRUE    )
    m_wnd_browser.GetControlUnknown()->QueryInterface(&m_browser);

  

    int _width = ::GetSystemMetrics(SM_CXSCREEN);
    int _height = ::GetSystemMetrics(SM_CYSCREEN);

    int _left = _width *0.05;
    int _top = _height *0.05;

    int _nwidth = _width *0.9;
    int _nheight = _height *0.9;


    ::SetWindowPos(m_hWnd, HWND_TOPMOST, _left, _top, _nwidth, _nheight, 0);
   

    return TRUE;  // return TRUE unless you set the focus to a control
                  // EXCEPTION: OCX Property Pages should return FALSE
}

Для того, что можно назвать ранней альфой осталось сделать немного:) Диалог перерыва появляется пустым. Нужна какая-то тестовая страница и код. который ее загружает.
Напишем index.html файл с таким содержанием

<table width=100% height=100% border=0>
<tr><td>
<center>
<img src="cup.png" align="middle">
</center>
</td></tr>
</table>

Где cup.png - это картинка чашки кофе:) (она есть в исходниках - взял я ее отсюда http://commons.wikimedia.org/wiki/Coffee_and_tea_icons)

Для загрузки используется такой код. LoadProject() надо добавить в конец DLG_SPLASH::OnInitDialog()

void DLG_SPLASH::LoadProject()
{
   
    CString m_project_path = GetFileDir() + "index.html";
   
    try
    {
        m_browser->Navigate((_bstr_t) m_project_path, NULL, NULL, NULL, NULL);
    }
    catch (_com_error &e)
    {
       
    }
}

CString DLG_SPLASH::GetFileDir()
{
    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 CString(sDrive) + sDir;
}

Показываем и прячем диалог вот так:

void DLG_SPLASH::SplashShow()
{
    ShowWindow(SW_SHOW);
}

void DLG_SPLASH::SplashHide()
{
    ShowWindow(SW_HIDE);
}

Не даем диалогу закрыться при нажатии Escape вот так:

BOOL DLG_SPLASH::PreTranslateMessage(MSG* pMsg)
{
   
    if (pMsg->message == WM_KEYDOWN)
        if (pMsg->wParam == VK_ESCAPE)
        {
       
            return true;
        }
   
    return CDialog::PreTranslateMessage(pMsg);
}

Для того, чтобы масштабировать эксплорер по всей площади диалога используем такой код:

void DLG_SPLASH::OnSize(UINT nType, int cx, int cy)
{
    CDialog::OnSize(nType, cx, cy);
   
    if (IsWindow(m_wnd_browser)) m_wnd_browser.MoveWindow(0,0,cx,cy);
   
}

Вот вроде и все:) Можно сказать, что готова первая альфа:) Вот исходники для VC++ 6

Скачать исходники.(http://www.programschool.tu2.ru/source/waterEyeKeeper.zip или http://program-school.narod.ru/source/waterEyeKeeper.zip)

В избранное