С++ вопрос о пикселях рисования


Как сделать окно или, скорее, область отсечения, где я смогу рисовать пиксели? Он может использовать WinApi, однако я не хочу, чтобы мой проект выглядел как winapi, поэтому он будет иметь

int main(){}

вместо

int WINAPI WinMain(HINSTANCE ...

Я нашел пример, где я могу рисовать в окне консоли

int main()
{
    COLORREF color = RGB(255,0,0); // COLORREF to hold the color info

    SetConsoleTitle("Pixel In Console?"); // Set text of the console so you can find the window

    HWND hwnd = FindWindow(NULL, "Pixel In Console?"); // Get the HWND
    HDC hdc = GetDC(hwnd); // Get the DC from that HWND

    for( int i = 0 ; i < 50 ; i++ )
    {
    SetPixel(hdc, 5+i, 12, color); // SetPixel(HDC hdc, int x, int y, COLORREF color)
    }
        ReleaseDC(hwnd, hdc); // Release the DC
    DeleteDC(hdc); // Delete the DC
    system("pause");
    return(0);
}

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

Также было бы здорово иметь возможность обрабатывать простые события клавиатуры/мыши для этой программы, но это не моя основная цель, возможно, с этим помогут какие-то другие сторонние библиотеки.

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

Буду благодарен за любую помощь.


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

" Иначе как Allegro/SDL создает окно? Они используют вызовы ассемблера или оболочки? Я буду намного счастливее, когда смогу создать окно с нуля, сколько бы работы это ни стоило :)"


person Neomex    schedule 01.01.2011    source источник
comment
Если вы хотите создать окно, используйте WINAPI, в сети и на msdn.microsoft.com есть множество примеров. Если вы используете WINAPI, ваша программа будет выглядеть так, как будто она использует WINAPI. В чем дело?   -  person frast    schedule 02.01.2011
comment
main() — это функция запуска консольных приложений. Вам не нужна консоль, поэтому вам нужно использовать WinMain.   -  person Dialecticus    schedule 02.01.2011
comment
@ Дэвид Хеффернан: Да, я считаю, что это правильно. На самом деле, WinMain — это макрос, который будет заменен на правильный оконный main в зависимости от того, скомпилировано ли приложение в режиме UNICODE или в режиме ASCII.   -  person gablin    schedule 02.01.2011
comment
@gablin @Dialecticus Я уверен, что вы могли бы написать консольное приложение с WinMain в качестве основного, и я уверен, что вы могли бы написать оконное приложение с основным в качестве основного и соответствующими параметрами.   -  person David Heffernan    schedule 02.01.2011
comment
@David Heffernan: Просто из интереса я погуглил и нашел эту ссылку: comsci. liu.edu/~murali/win32gui/Win32Apps.htm Однако здесь показано, как создать окно консоли в оконном режиме, но не окна в консольном режиме.   -  person gablin    schedule 03.01.2011


Ответы (5)


Вам это не понравится - в Windows вы должны создать окно, затем переопределить сообщение WM_PAINT, а затем нарисовать то, что вы должны нарисовать, когда вас вызывают из системы. Это старомодный способ делать вещи, и это не так уж плохо.

Несколько интересных и актуальных ссылок:

http://www.winprog.org/tutorial/bitmaps.html

http://www.codeproject.com/Articles/66250/BeginPaint-EndPaint-or-GetDC-ReleaseDC.aspx

Если вы действительно хотите избежать всего этого, попробуйте popcap. Кривая обучения, связанная с этим, может быть круче, поэтому вы, вероятно, действительно захотите придерживаться GDI и HWND, независимо от того, насколько сложным и запутанным это может показаться в начале.

person Daniel Mošmondor    schedule 01.01.2011

Я предлагаю вам попробовать OpenGL вместе с GLFW или перенасыщение. С OpenGL вы сможете обрабатывать все, что связано с обработкой графики (рендеринг 2D/3D), а роль библиотеки GLFW, например, заключается в добавлении некоторых функций, таких как: управление окнами, управление событиями, таймеры, потоки и т. д. .

Личное примечание, идите на GLFW, потому что перенасыщение больше не поддерживается, я думаю...

person Amokrane Chentir    schedule 01.01.2011
comment
Истинный. GLFW рулит, то же самое и с SDL. (И GLUT, не говоря уже о прекращении его поддержки, имеет очень странный API...) - person Kos; 02.01.2011

Короче говоря: вы должны использовать графический фреймворк / набор инструментов для виджетов, чтобы создать окно и начать оттуда.

Затем, в зависимости от того, какую структуру вы используете, вы затем создадите окно и измените пиксели в соответствии с его ссылкой.

Я рекомендую SDL (маленький, вероятно, именно то, что вам нужно), Allegro (похожий) или Qt (большой).

person Kos    schedule 01.01.2011
comment
Мне нужна библиотека, которая не использует/в основном не основана на видеокарте, так как она должна будет работать в режиме VGASAVE, но с другой стороны, как Allegro/SDL создает окно? Они используют вызовы ассемблера или оболочки? Я буду намного счастливее, когда смогу создать окно с нуля, сколько бы это ни стоило труда :) - person Neomex; 02.01.2011
comment
SDL в порядке, используйте SDL_SetVideoMode(x,y,bpp, SDL_SWSURFACE | SDL_DOUBLEBUFFER). - person Kos; 02.01.2011
comment
Возможно ли то же самое с allegro5? - person Neomex; 02.01.2011
comment
Конечно. См. allegro.cc/manual/5/graphics.html и allegro.cc/manual/5/primitives.html . Руководство обычно является подходящим местом для быстрой оценки возможностей библиотеки. - person Kos; 02.01.2011

Иначе как Allegro/SDL создает окно? Они используют вызовы ассемблера или оболочки? Я буду намного счастливее, когда смогу создать окно с нуля, сколько бы это ни стоило труда :)

person Neomex    schedule 01.01.2011

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

// Set text of the console so you can find the window
SetConsoleTitle("Pixel In Console?"); 
HWND hwnd = FindWindow(NULL, "Pixel In Console?"); // Get the HWND
HDC hdc = GetDC(hwnd); // Get the DC from that HWND

Но Windows обновляет имя вашего окна только через некоторое время, поэтому, если вы заставите эти операторы выполняться один за другим, оператор HWND hwnd = FindWindow(NULL, "Pixel In Console?"); не сможет найти такое окно, потому что Windows требуется время, чтобы обновить заголовок, как это сделано: SetConsoleTitle("Pixel In Console?");

Решение. Вы можете оставить Sleep(int); (включая windows.h) или использовать:

HWND hwnd = FindWindowA("ConsoleWindowClass",NULL); // Get the HWND

вместо

SetConsoleTitle("Pixel In Console?"); // Set text of the console so you can find the window HWND hwnd = FindWindow(NULL, "Pixel In Console?"); // Get the HWND

Вот пример программы:

#include <windows.h>
#include<conio.h>`
#include<iostream.h>`

POINT p;    //structure with coordinates to mouse location`

void main()
{
    COLORREF color = RGB(255,0,0); // COLORREF to hold the color info`

    HWND hwnd = FindWindowA("ConsoleWindowClass",NULL); // Get the HWND
    HDC hdc = GetDC(hwnd); // Get the DC from that HWND

    for( int i = 0 ; i < 400 ; i++ )
    {
        for(int j=0;j<50;j++)
            SetPixel(hdc, i, j, color);
    }
    while(1)
    {
          GetCursorPos(&p);
          ScreenToClient(hwnd,&p);
          cout<<p.x<<' '<<p.y;
          clrscr();
          if(GetAsyncKeyState(1)) //checks if left mouse button is pressed
          {
                //fool around with these functions:
                SetPixel(hdc,p.x,p.y,color); 
                //LineTo(hdc,p.x,p.y);
                //Rectangle(hdc,200,200,p.x,p.y);
                Sleep(10);
          }
    }
    ReleaseDC(hwnd, hdc); // Release the DC
    DeleteDC(hdc); // Delete the DC
    system("pause");
}

Это мой первый ответ. Надеюсь, я помог, и мне потребовалось много времени, чтобы найти эти функции, кроме того, я думаю, что узнал больше из вашего скрипта, чем показал вам :)

person reubenjohn    schedule 26.02.2013
comment
Можно ли дождаться обновления заголовка окна, если вы уже получили hwnd? - person anatoly techtonik; 10.01.2014
comment
После того, как вы успешно создали свою переменную hwnd, не имеет значения, какой у вас заголовок окна! Так что не стесняйтесь менять название :) - person reubenjohn; 13.01.2014