Графика в MS Visual 2005 C++

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
Vladimir89
Сообщения: 75
Зарегистрирован: 21 май 2007, 02:25

28 окт 2008, 19:27

Я умею кодить в Си++ только в ДОСе. Тоесть консольными приложениями все мои знания ограничиваются.
Я ДОЛЖЕН научиться писать проги для Windows. С интерфейсом, все дела.
Конечно же я попытался разобраться во всем сам - по книжкам.
Не получилось (или недостаточно упорно сидел).
В общем я кое что понял, но соединить воедино полученные знания не могу.

Вот моя задача: вывести на окне много точек имеющих рандомные координаты.

Если у меня это получится - я буду счастлив.

А теперь к делу. Вот вопросы которые у меня возникли:
-приложение какого типа лучше для этого создать? MFS или просто win32 project ?
-мне нужно знать КУДА КОНКРЕТНО МНЕ ВПИСЫВАТЬ КОД КОТОРЫЙ РЕАЛИЗУЕТ АЛГОРИТМ РИСОВАНИЯ ТОЧЕК НА ЭКРАНЕ.
-мне нужен пример кода. Такого кода, что засунув его в функцию onDraw мне на экране нарисуется ХОТЯБЫ ТОЧКА. Я знаю что это можно сделать 2мя способами: через документ или напрямую. Мне бы лучше напрямую (проще).
Буду благодарен даже за самую мааленькую помощь :)
Си ++
Здоровье --
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

29 окт 2008, 10:51

1. Я бы обошёлся обычным Win32 project. В этом случае нам не нужно тянуть за собой тяжеловесную, и абсолютно ненужную MFC. Однако создание Win32 project подразумевает наличие некторых знаний об архитектуре Win32 приложений, как-то: понятия класса окна, процедуры создания окна, цикла обработки сообщений и т.д. Если тебя это не пугает, то однозначно Win32 project.

2. Если создашь Win32 project, то код по отрисовке нужно будет поместить в обработчик сообщения WM_PAINT твоего окна.

3. Ответом на третий вопрос может послужить пример кода для функции BeginPaint, взятый из MSDN:

Код: Выделить всё

LRESULT APIENTRY WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    PAINTSTRUCT ps; 
    HDC hdc; 
 
    switch (message) 
    { 
        case WM_PAINT: 
            hdc = BeginPaint(hwnd, &ps); 
            TextOut(hdc, 0, 0, "Hello, Windows!", 15); 
            EndPaint(hwnd, &ps); 
            return 0L; 

        // Process other messages.  
    } 
} 
В этом коде досточно заменить вызов TextOut на вызов Ellipse, чтобы получить маленький залитый круг, который вполне сойдёт за точку.

Старый GDI поддерживается только для обеспечения совместимости. Вот ещё один пример из того же MSDN. Здесь используется более прогрессивный объектно-ориентированный механизм рисования GDI+. Он обеспечивает более высокий перфоменс и большие возможностей, потому он предпочтителен для использования.

Код: Выделить всё

#define UNICODE
#include <windows.h>
#include <gdiplus.h>
using namespace Gdiplus;

VOID OnPaint(HDC hdc)
{
   Graphics graphics(hdc);
   Pen      pen(Color(255, 0, 0, 255));
   graphics.DrawLine(&pen, 0, 0, 200, 100);
}

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

INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR, INT iCmdShow)
{
   HWND                hWnd;
   MSG                 msg;
   WNDCLASS            wndClass;
   GdiplusStartupInput gdiplusStartupInput;
   ULONG_PTR           gdiplusToken;
   
   // Initialize GDI+.
   GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
   
   wndClass.style          = CS_HREDRAW | CS_VREDRAW;
   wndClass.lpfnWndProc    = WndProc;
   wndClass.cbClsExtra     = 0;
   wndClass.cbWndExtra     = 0;
   wndClass.hInstance      = hInstance;
   wndClass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
   wndClass.hCursor        = LoadCursor(NULL, IDC_ARROW);
   wndClass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
   wndClass.lpszMenuName   = NULL;
   wndClass.lpszClassName  = TEXT("GettingStarted");
   
   RegisterClass(&wndClass);
   
   hWnd = CreateWindow(
      TEXT("GettingStarted"),   // window class name
      TEXT("Getting Started"),  // window caption
      WS_OVERLAPPEDWINDOW,      // window style
      CW_USEDEFAULT,            // initial x position
      CW_USEDEFAULT,            // initial y position
      CW_USEDEFAULT,            // initial x size
      CW_USEDEFAULT,            // initial y size
      NULL,                     // parent window handle
      NULL,                     // window menu handle
      hInstance,                // program instance handle
      NULL);                    // creation parameters
	  
   ShowWindow(hWnd, iCmdShow);
   UpdateWindow(hWnd);
   
   while(GetMessage(&msg, NULL, 0, 0))
   {
      TranslateMessage(&msg);
      DispatchMessage(&msg);
   }
   
   GdiplusShutdown(gdiplusToken);
   return msg.wParam;
}  // WinMain

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, 
   WPARAM wParam, LPARAM lParam)
{
   HDC          hdc;
   PAINTSTRUCT  ps;
   
   switch(message)
   {
   case WM_PAINT:
      hdc = BeginPaint(hWnd, &ps);
      OnPaint(hdc);
      EndPaint(hWnd, &ps);
      return 0;
   case WM_DESTROY:
      PostQuitMessage(0);
      return 0;
   default:
      return DefWindowProc(hWnd, message, wParam, lParam);
   }
} // WndProc
По нюансам обращайся - помогу.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Decoder
Сообщения: 303
Зарегистрирован: 19 фев 2008, 23:11
Откуда: Moscow

29 окт 2008, 15:44

Точку нарисовать можно с помощью функции PutPixel(), но она работает медленно, поэтому когда точек много, то лучше ей не пользоваться, а формировать рисунок сначала в памяти через битмап, а потом этот битмап выводить на экран.
Я когда-то делал подобную программу, там множество точек псевдослучайным образом заполняет пространство окна, но при этом они ещё движутся по экрану сверху вниз, создавая эффект дождя. Можешь её скачать и запустить у себя.

P.S. Как мне помнится, вопрос про графический интерфейс Windows ты задавал ещё в начале года. За это время не научился точки на экране рисовать?
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

29 окт 2008, 16:25

&quot писал(а):а формировать рисунок сначала в памяти через битмап, а потом этот битмап выводить на экран.
Это уже нюансы, которые можно постичь позже. Дай человеку с нюансами разобраться.

По теме. Есть уж совсем честным быть, я бы настаивал на использовании GDI+, а ещё лучше использовать DirectDraw. Но для учебных целей вполне достаточно обычного GDI даже без буферизации.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Vladimir89
Сообщения: 75
Зарегистрирован: 21 май 2007, 02:25

30 окт 2008, 02:05

Псибо большое!
Но я щас пока не могу с API разбираться - мало времени!
У меня получилось при помощи MFS нарисовать крестик!!!
Значит я буду с MFS проектом работать... + книжки в основном по нему.

Теперь самый главный вопрос для того чтобы завершить мою задачу:
куда пихать код в MFS проекте который бы задавал условие расположения точек(т.е. саму программу)?
Тоесть где создавать массив, генерить координаты и т.д. ?
Си ++
Здоровье --
Аватара пользователя
Vladimir89
Сообщения: 75
Зарегистрирован: 21 май 2007, 02:25

30 окт 2008, 02:08

Decoder писал(а):P.S. Как мне помнится, вопрос про графический интерфейс Windows ты задавал ещё в начале года. За это время не научился точки на экране рисовать?

Простите меня) Я не пацан - за слова не отвечаю :D
Тупо у нас не было пол года программирования. Еще я влюбился очень круто и неудачно. Поэтому было как то не до этого. Хотел летом заняться этим делом, но так и не начал)))
А сейчас, третий курс... пришли мы на пару, а нам там задание! Вот такое! А мы еле еле Визуалом пользоваться умеем! Вот и пришлось в срочном порядке во всем разбираться!
Си ++
Здоровье --
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

30 окт 2008, 09:47

&quot писал(а):Теперь самый главный вопрос для того чтобы завершить мою задачу:
куда пихать код в MFS проекте который бы задавал условие расположения точек(т.е. саму программу)?
Тоесть где создавать массив, генерить координаты и т.д. ?
Массив нужно запихнуть в класс-документ. Этот класс имеет стандартное название C<ИмяПроекта>Doc. Для того, чтобы вписать в массив просчитанные координаты, нужно у этого класса перегрузить метод OnNewDocument и сделать это там. Отображать массив в точки на экране нужно в классе-виде (C<ИмяПроекта>View) в перегруженном методе OnDraw.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Vladimir89
Сообщения: 75
Зарегистрирован: 21 май 2007, 02:25

30 окт 2008, 16:57

Romeo писал(а):Массив нужно запихнуть в класс-документ. Этот класс имеет стандартное название C<ИмяПроекта>Doc. Для того, чтобы вписать в массив просчитанные координаты, нужно у этого класса перегрузить метод OnNewDocument и сделать это там. Отображать массив в точки на экране нужно в классе-виде (C<ИмяПроекта>View) в перегруженном методе OnDraw.

нужно у этого класса перегрузить метод OnNewDocument
вот как это сделать? Я знаю что такое перегрузка, но как это применить к данной ситуации я не понимаю :(
Си ++
Здоровье --
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

30 окт 2008, 18:25

Если быть совсем точным, то правильнее было сказать переопредели, а не перегрузи. Но я думал, что ты поймёшь что к чему. Ты ведь сам написал, что
&quot писал(а):Я умею кодить в Си++
:)

В общем делай так. Найди в базовом классе с именем CDocument виртуальный метод OnNewDocument скопируй его объявления, вставь объявление в твой отнаследованный класс-документ и определи в cpp файле его тело, в котором реализуй алгоритм для вычисления элементов массива.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Vladimir89
Сообщения: 75
Зарегистрирован: 21 май 2007, 02:25

30 окт 2008, 21:23

Romeo писал(а): В общем делай так. Найди в базовом классе с именем CDocument виртуальный метод OnNewDocument скопируй его объявления, вставь объявление в твой отнаследованный класс-документ и определи в cpp файле его тело, в котором реализуй алгоритм для вычисления элементов массива.

-Найди в базовом классе с именем CDocument виртуальный метод OnNewDocument скопируй его объявления - сделал BOOL CdevelopingDoc::OnNewDocument()
-вставь объявление в твой отнаследованный класс-документ - а вот это я уже не понял :(
я тупой =\
Си ++
Здоровье --
Ответить