Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   C++ граф. задача нужна помощь (https://forum.antichat.xyz/showthread.php?t=40500)

Visor 21.05.2007 00:37

C++ граф. задача нужна помощь
 
Здравствуйте, уважаемые участники форума. Получил вот такое задание, но возникли проблемы...
Программа Win32 для рисования на экране прямых линий. Начало и конец линии задаются двумя последовательными нажатиями на левую кнопку мыши в основном окне программы. Нажатие на правую очищает экран. Также должен автоматически очищаться через время t после рисования последней линии. Добиться сохранения рисунка при помощи memory bitmaps после перекрытия окна лругими окнами.
При выборе свойства линии, программа должна вывести диал. окно. в checkbox выбираем тип (штриховая или сплошная). А radio buttons для цветов.
Таймаут - тут задается t.
Выход - запрашивает о выходе, и при утвердительном ответе обновить в ini-файле все параметры (тип линии, время таймаута), после этого завершить работу. При повторном запуске, программа загрузит сохраненные параметры из ini-файла.
Проблема в том, что программа виснет при выборе дочернего элемента в гл. меню. Кроме того она не рисует штриховые линии :confused: . Я пробовал менят время задержки, последовательно комментировать те или иные функции и пр., с отладчиком. Ничего. Мне кажется, что дело в WM_PAINT. Иногда получалось по-отдельности включать нужные функции, но все вместе - никогда не работало. :( Сам над этим уже два месяца голову ломаю, ничего не могу сделать.
Если совсем никак, то можете удалить пост или не смотреть вообще.
С меня много плюсиков, если получится!
Проект (включая resource.h и пр.) для MSVS 2005 выложил тут в *.rar
А вот то нечто, что мне удалось написать:
Код:

#include <windows.h>
#include <stdio.h>
#include "resource.h"
#define  TIMER_ID 1
 
HINSTANCE hhh;

int dedit=5;
int colornumber=1;
bool linestyle=false;
bool startline=true;
bool t=false;
int x,y,x0,y0;

HPEN pen;

LRESULT CALLBACK WindowFunc(HWND,UINT,WPARAM,LPARAM);

//-------------------------------------------------------------------
// WinMain
//-------------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hThisInst,
                                            HINSTANCE hPrevInst,
                                            LPSTR lpszArgs,
                                            int nWinMode)
{
  char szWinName[] = "класс окна";
  MSG msg;
  HWND hwnd;
  WNDCLASS wcl;
 
  hhh=hThisInst;

  // класс окна
  wcl.hInstance = hThisInst;    //идентификатор приложения
  wcl.lpszClassName = szWinName; //имя класса окна
  wcl.lpfnWndProc = WindowFunc;  //функция окна
  wcl.style = 0;                // стиль по умолчанию
  wcl.hIcon = LoadIcon(NULL,IDI_APPLICATION); //стандартная иконка
  wcl.hCursor = LoadCursor(NULL,IDC_ARROW);  //стандартный курсор мыши
  wcl.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);      //без меню 
  wcl.cbClsExtra = 0;
  wcl.cbWndExtra = 0;
  wcl.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH); // Цвет фона окна
 
  if (!RegisterClass (&wcl)) return 0;
 
  // CreateWindow
  hwnd = CreateWindow(szWinName,"Мое первое оконо",
            WS_OVERLAPPEDWINDOW,
                  CW_USEDEFAULT, // горизонтальное положение окна
                  CW_USEDEFAULT, // вертикальное положение окна       
                  CW_USEDEFAULT, // ширина окна       
                  CW_USEDEFAULT, // высота окна       
                  HWND_DESKTOP,
                  NULL,
                  hThisInst,
                  NULL);

  // Показать окно и нарисовать содержимое
  ShowWindow(hwnd,nWinMode);
 
  // Цикл обработки сообщений
  while (GetMessage (&msg, NULL, 0, 0))
  {
          TranslateMessage (&msg);
          DispatchMessage (&msg);
  }

  return msg.wParam;
}                         
 
//-------------------------------------------------------------------

//диалоговое окно

BOOL CALLBACK DialogProcTime(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{  char str[10];
        switch (uMsg)
        {
        case WM_INITDIALOG:
                sprintf(str,"%d",dedit);
                SetDlgItemText(hDlg,IDC_EDIT1,str);
                return TRUE;
                break;
    case WM_COMMAND:
                switch(LOWORD(wParam))
                {
                case IDOK:
            GetDlgItemText(hDlg,IDC_EDIT1,str,10);
                        dedit = atoi(str);
                  EndDialog(hDlg,TRUE);
                        return TRUE;
                        break;
                case IDCANCEL:
                        EndDialog(hDlg,TRUE);
                        return TRUE;
                        break;
                }
                break;
        }
        return FALSE;
}



//диалоговое окно

BOOL CALLBACK DialogProcSvoistva(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)

        /*
        switch (uMsg)
        {
        case (WM_INITDIALOG):
                CheckRadioButton(hDlg, IDC_RADIO1, IDC_RADIO5, IDC_RADIO1+colornumber-1);
                if (linestyle)
                  CheckDlgButton(hDlg, IDC_CHECK1, BST_CHECKED);
                else
          CheckDlgButton(hDlg, IDC_CHECK1, BST_UNCHECKED);
                return TRUE;
                break;
    case WM_COMMAND:
                switch(LOWORD(wParam))
                {
                case IDOK:
            if (IsDlgButtonChecked(hDlg, IDC_RADIO1))
              colornumber=1;
                        if (IsDlgButtonChecked(hDlg, IDC_RADIO2))
              colornumber=2;
                        if (IsDlgButtonChecked(hDlg, IDC_RADIO3))
              colornumber=3;
                        if (IsDlgButtonChecked(hDlg, IDC_RADIO4))
              colornumber=4;
                        if (IsDlgButtonChecked(hDlg, IDC_RADIO5))
              colornumber=5;
                        if (IsDlgButtonChecked(hDlg, IDC_CHECK1))
              linestyle=true;
                        else
              linestyle=false;
                  EndDialog(hDlg,TRUE);
                        return TRUE;
                        break;
                case IDCANCEL:
                        EndDialog(hDlg,TRUE);
                        return TRUE;
                        break;
                }
                break;
 }
*/
        return FALSE;
}



// Функция - обработчик сообщений окна
//-------------------------------------------------------------------
LRESULT CALLBACK WindowFunc(HWND hwnd,UINT message,
                                                  WPARAM wParam,LPARAM lParam)

  PAINTSTRUCT ps;
  HDC dc;
  HPEN blackpen,whitepen,redpen,greenpen,bluepen;
 

 
  switch (message)
  {
    case WM_DESTROY:
                    PostQuitMessage(0);
                      break;

    case WM_COMMAND:
        switch(LOWORD(wParam))
                {
                case ID_EXIT:
            if (MessageBox(hwnd,"Действительно ли вы хотите выйти?","",MB_OKCANCEL)==IDOK)
                        {
                                PostQuitMessage(0);
                        }
                        break;
                case ID_TIMEOUT:
                        DialogBox(hhh,MAKEINTRESOURCE(IDD_DIALOG1),hwnd,DialogProcTime);                     
                        break;
                case ID_SVOISTVA:                       
                            DialogBox(hhh,MAKEINTRESOURCE(IDD_DIALOG2),hwnd,DialogProcSvoistva);                               
                        break;
                }
                break;
      case WM_PAINT:                 
                if (t)
                {
                      dc=BeginPaint(hwnd, &ps);
                          if (startline)
                          {
                                  x0=x;
                                  y0=y;
                                  startline=false;
                          }
                          else
                          {

                                  blackpen=CreatePen(PS_SOLID,2,RGB(0,0,0));
                                  whitepen=CreatePen(PS_SOLID,2,RGB(255,255,255));
                  redpen=CreatePen(PS_SOLID,2,RGB(255,0,0));
                  greenpen=CreatePen(PS_SOLID,2,RGB(0,255,0));
                  bluepen=CreatePen(PS_SOLID,2,RGB(0,0,255));
                                  if (colornumber==1) SelectObject(dc,blackpen);
                                  if (colornumber==2) SelectObject(dc,whitepen);
                                  if (colornumber==3) SelectObject(dc,redpen);
                                  if (colornumber==4) SelectObject(dc,greenpen);
                                  if (colornumber==5) SelectObject(dc,bluepen);
                                  MoveToEx(dc, x0, y0, NULL);
                                  LineTo(dc, x, y);
                                  startline=true;
                                  SetTimer(hwnd,TIMER_ID,1000*dedit,NULL);
                          }
                          EndPaint(hwnd, &ps);
                }
                          break;
      case WM_LBUTTONDOWN :                 
                          x=LOWORD(lParam);
                          y=HIWORD(lParam);
                          t=true;
                          InvalidateRect(hwnd,0,FALSE);
              UpdateWindow(hwnd);
                          break;
      case WM_RBUTTONDOWN :
              t=false;
                      InvalidateRect(hwnd,0,TRUE);
              UpdateWindow(hwnd);
                          startline=true;
                          break;
          case WM_TIMER:
                      KillTimer(hwnd,TIMER_ID);
              t=false;
                          InvalidateRect(hwnd,0,TRUE);
              UpdateWindow(hwnd);
                      break;
                 
          default:
                  return DefWindowProc (hwnd, message, wParam, lParam);
  }

  return 0;
}

Спасибо заранее, если посмотрите, так как в C++ я совсем чайник.

nerezus 21.05.2007 07:14

Тебе обязательно на апях?

Visor 21.05.2007 10:49

да, вообще задача поставлена именно для выполнения в windows api

hidden 21.05.2007 11:09

Сейчас времени уже нету, позже посмотрю внимательнее.
Она кстати у тебя не виснет, просто создаёт диалог но фокус на него не передаёт(без нажатия alt), похоже что фокус остаётся у меню бара, почему я так и не понял...

1) Тело функции обработки диалога зря закоментил.
2) return TRUE не везде возвращяешь.

Visor 21.05.2007 12:21

Да, вижу, только вот не понимаю, в чем дело с ALTом и что не рисуются штриховые :confused:

hidden 22.05.2007 02:36

У тебя с проектом что-то не так, я так и не нашел что, создай новый проект, НЕ КОПИРУЙ диалоговые окна, пункты меню и даже их элементы, не копируй свои функции, делай точно как в заготовке проекта и должно всё работать :)

Я пробовал создать новый проект, скопировать туда твой диалог и функцию колбэка и получилась та-же чушь, так что НЕ КОПИРУЙ.

Насчёт пунктиров, так функция CreatePen не умеет рисовать пунктиры шире одного пикселя, вроде-бы ExtCreatePen умеет или используй "GDI Plus"

scrat 22.05.2007 19:00

блин писал графы правда не win api если понадобяться какие-нить алгоритмы стучи в 213947843 помогу

Visor 22.05.2007 20:44

Респект! :)
Вобщем, с текстом можно так, насколько я понял:
Код:

void CTextWnd::OnPaint()
{
  CPaintDC dc(this);
  dc.SetTextColor(clrText);
  dc.SetBkColor(::GetSysColor(COLOR_WINDOW));
  CRect rect;
  GetClientRect(rect);
  dc.DrawText(_TEXT("Обработка WM_PAINT"), -1, rect,
 DT_SINGLELINE | DT_CENTER | DT_VCENTER);
}

Вот. Что касается нетекстовых элементов, то, видимо нужно использовать memory bitmaps (как-то :confused: ). То есть можно и без этого, но если графики много, всё же оно целесообразно.
Цитата:

Насчёт пунктиров, так функция CreatePen не умеет рисовать пунктиры шире одного пикселя, вроде-бы ExtCreatePen умеет или используй "GDI Plus"
Странно, вроде если брать CreatePen, то можно пользоваться либо PS_SOLID, либо PS_DASH.
Или я тут что-то напутал с CreatePen и ExtCreatePen.

P.S. Половину дня убил на поиски ресурсов по теме.
Нашёл вот эту статью -- вполне информативно!
Ладно, я ещё покопаюсь. Надеюсь, всё же озарение будет :) -- тогда обязательно отпишусь!

hidden 22.05.2007 21:19

Цитата:

Сообщение от Visor
Странно, вроде если брать CreatePen, то можно пользоваться либо PS_SOLID, либо PS_DASH.
Или я тут что-то напутал с CreatePen и ExtCreatePen.

http://msdn2.microsoft.com/en-us/library/aa922162.aspx
Цитата:

If the value specified by nWidth is greater than 1, the fnPenStyle parameter must be PS_NULL or PS_SOLID.


Время: 12:33