Пятница, 15 Ноября 2024, 09:29

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Tutorial [EN/RU]: создание окна приложения, WinAPI
WXZRWДата: Суббота, 08 Августа 2009, 16:15 | Сообщение # 1
Thousand faces conspiration
Сейчас нет на сайте
Последнее обновление 09/08/2009

Решил выложить сейчас, в принципе, код откомментирован на английском, но прочие обьяснения пока что будут на русском, а потом я добавлю и на английском. Сам туториал очень простой, без использования OpenGL или DirectX, чтобы не возникало дополнительных сложностей, поскольку все это в принципе предназначено для самых новичков, если вы уже обладаете такими знаниями, то дальше можете не читать.

Ну и также сперва предупреждение : любая информация которая здесь предоставлена, может содержать те или иные неточности, код может не компилиться при некоторых условиях. Все что здесь есть, предоставлено мною без каких-либо гарантий и ответственности, и я не несу никакой ответственности за любой возможный ущерб, который может быть вызван использованием любой части данного поста, кода или информации в любом виде и при любых обстоятельствах.

Далее код и инфа по коду :

Code
#include <windows.h>

// Declare some variables and function prototypes for further usage

* Сперва обьявим функции и переменные :

Первые три вещи это контекст устройства (device context), хендл окна (window handle), и инстанс приложения (application instance)

Code

HDC dc;

HWND w_handle;
HINSTANCE inst;

LRESULT CALLBACK w_process(HWND wnd_handle,UINT system_msg,WPARAM w_param,LPARAM l_param);

WPARAM _process(HWND w_handle);

// Below functions we need

* Главная функция, здесь устанавливаем все настройки и создаем окно, также как и класс приложения. Точнее, это точка входа в приложение.

Code
// Main function
int WINAPI WinMain(HINSTANCE inst,HINSTANCE prev_inst,LPSTR line,int show)
{
// We want window styles at first

DWORD ex_style;
DWORD style;

// We 'll need it later to set up window size and position.

* Сперва создадим структуры для класса и для окна, заполним их переменными и создадим класс.

Code
RECT rect;

// And at last we need to set a window class

WNDCLASSEX w_class;

// Allocate memory for class structure

[b]* Выделим память под структуру класса[/b]

memset(&w_class,0,sizeof(WNDCLASSEX));

// Set up class variables below

* Параметры переменных класса, лучше всего посмотреть инфу на MSDN по структуре WNDCLASSEX, поскольку тут могут быть варианты, то есть в данном случае я использовал одни параметры, но в других случаях могут быть использованы и другие параметры.

* Дополнительно : этот параметр (hbrBackground) может быть определен как NULL, в таком случае окно не будет закрашено. Многие авторы (особенно те кто пишет туториалы под OpenGL/DirectX) не утруждаются этим, но я задал черный цвет.

Code
w_class.cbClsExtra = 0; // extra bytes, we want it to be 0
w_class.cbSize = sizeof(WNDCLASSEX); // size of the whole structure
w_class.cbWndExtra = 0; // yet another extra bytes, shulda be 0 in our case
w_class.hbrBackground = (HBRUSH)(COLOR_WINDOW+2); // set up background color, it 'll be black.
//if you want it to be white, set +1 instead +2 then
w_class.hCursor = LoadCursor(NULL,IDC_ARROW); // we 'll set standard cursor, but you can set your own one
w_class.hIcon = LoadIcon(NULL,IDI_APPLICATION); // standard icon, but culda be NULL instead of it also
w_class.hIconSm = LoadIcon(NULL,IDI_WINLOGO); // same as above
w_class.hInstance = inst; // handle to instance
w_class.lpfnWndProc = w_process; // pointer to window procedure
w_class.lpszClassName = "test"; // class name
w_class.lpszMenuName = NULL; // menu name, but if set to NULL, window have no default menu then
w_class.style = CS_HREDRAW | CS_VREDRAW; // set class style(s)

// After class infromation is OK and available, it's time to register the class

* Когда все параметры класса заданы, можно его зарегистрировать в системе, но не наоборот.

Code
RegisterClassEx(&w_class);

// Window styles below

style = WS_OVERLAPPEDWINDOW;
ex_style = WS_EX_APPWINDOW;

// Window rect to set window size (width and height), and window position (left and top)
// Note that 0,0 yields a top left corner of the screen

* Теперь можем приступать к созданию окна, для начала надо задать позицию окна на экране и размеры окна.

* Дополнительно : left и top это координаты верхнего левого угла окна, у нас это точка отсчета коодинат экрана, то есть начало координат 0,0 это верхний левый угол экрана

Code
rect.bottom = 480;
rect.left = 0;
rect.right = 640;
rect.top = 0;

// Before creating the window we also need to set up window rectangle and style

* После того как структура заполнена, вызываем функцию AdjustWindowRect чтобы применить все параметры, которые были заданы.

* Дополнительно : эта функция используется перед созданием окна, если окно уже создано, то для изменения параметров RECT нужно использовать функцию SetWindowPos

Code
AdjustWindowRect(&rect,style,FALSE); // This one only valid before window is created, to change rect of existing window
// you shulda be using SetWindowPos function from WinAPI

// Ok, we're ready to create it

* Создаем само окно, опять же рекомендую смотреть в MSDN какие здесь именно параметры вообще могут быть.

Code
w_handle = CreateWindowEx(
ex_style, // window style (extended), we had to set up before
"test", // class name
"Test", // window name
style, // yet another window style
0, // horisontal window position
0, // vertical window position
rect.right - rect.left, // window width
rect.bottom - rect.top, // window height
NULL, // handle for parent window, it's NULL 'coz we have no such window
NULL, // handle for menu, it's NULL as well
inst, // handle to instance
NULL); // Additional info, but we don't want it at all, so it's NULL too

// Now let's set window position as well, but note it ain't really necessary, if we 'll skip this, window 'll
// be applied to the top left of screen


* Эту функцию можно и не вызывать, я делаю это чтобы показать, как изменить положение окна. Вообще при этом должно быть обработано соответствующее системное сообщение в нашей функции w_process, но для простоты я этого не стал делать, тем более что двигаем окно в самом
начале перед его созданием.

* Дополнительно : мы здесь не изменяем размер окна, только позицию. Поэтому последний параметр у нас SWP_NOSIZE, два предыдущих параметра также NULL. Если нужно изменить размер окна, тогда размеры нужно указать вместо NULL и также изменить последний параметр.

Code
SetWindowPos(
w_handle, // window handle
HWND_TOP, // how it shulda behave, we wanna it on the top of
240, // where the left side shulda be
320, // same for top, note both variables given in client coords
NULL, // specify new width of the window
NULL, // same for height, this one and above shulda be given in pixels, but note we don't want it that way
SWP_NOSIZE); // 'coz we want 2 items we have above to bee ignored, we set NOSIZE to remain window as it is

// We now want to set up window show state

* Теперь задаем стэйт окна, в данном случае все оставляем как есть по умолчанию, но можно и другой параметр указать, например SW_SHOWMAXIMIZED, тогда окно будет развернуто на весь экран.

Code
ShowWindow(w_handle,SW_SHOW); // window handle and yet another param to make our window active

* Показываем курсор мыши, или можно его убрать, тогда пишем false

Code
ShowCursor(true); // show mouse cursor too, if no longer required it culda be set to FALSE then

UpdateWindow(w_handle); // update window

return _process(w_handle); // return result back to, after it's handled by _process function
}


* Здесь отслеживаем системные сообщения и обрабатываем их. Опять же, советую смотреть в MSDN по поводу сообщений.

Code
// Shulda be declared within the class in WinMain function
LRESULT CALLBACK w_process(HWND w_handle,UINT _msg,WPARAM wparam,LPARAM lparam)
{
LONG lret = 0;

// Below we need to handle system messages, but we only take care about WM_CLOSE

* Обрабатываем только WM_CLOSE, остальные сообщения игнорируем и передаем дальше

Code
switch(_msg)
{

case WM_CLOSE : // Exit from application if WM_CLOSE command incoming
{

* Если поступило сообщение о закрытии окна, тогда удаляем из памяти device context и класс

Code
ReleaseDC(w_handle,dc); // Release device context from memory

UnregisterClass("Test",inst); // Remove our class too

PostQuitMessage(0); // Kill application
}
break;

default :

* Те сообщения, которые мы здесь не обработали, обрабатываются по умолчанию

Code
lret = DefWindowProc(w_handle,_msg,wparam,lparam); // Default processing for all the messages not processed by
// our application, to make sure that all the messages are processed anyway.

break;
}

return lret;
}

* Ну и здесь главный цикл приложения, беконечный

Code
// We will pass window handle to this one in WinMain function (at the end of)
WPARAM _process(HWND w_handle)
{
MSG msg;

// This one is the main application loop, it's infinite.

while(1)
{

* Обрабатываем системные сообщения

Code
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Dispatch system messages
{
if(msg.message == WM_QUIT) break; // If got WM_QUIT message then break the loop and exit from application

TranslateMessage(&msg);    // Otherwise, let's find out what the message is exactly
DispatchMessage(&msg); // And execute it

// Here we culda have an else statement and some stuff inside of it, for example, scene rendering, but we leave
// it as is, 'coz we have nothing to do at this time.

* Здесь можно было бы рендерить сцену, но так ее попросту нет, то ничего не делаем.

Code
}
}

return(msg.wParam);
}

Также прикладываю и .cpp исходник, для компиляции в Visual C++ нужно создать проект типа Win32 Application.

Ну и если нужно больше по-русски, то пишите запросы, хотя я позже планирую дописать еще инфы здесь. Следующий туториал будет о подключении OpenGL.

Прикрепления: core.cpp (6.2 Kb)
nilremДата: Суббота, 08 Августа 2009, 16:36 | Сообщение # 2
Просветленный разум
Сейчас нет на сайте
WXZRW
Извини, но это пока не туториал, а просто исходный код с комментариями и ничего больше.
Что такое HDC, HWND, HINSTANCE и т.д.?
Вот если ты и об этом вкратце упомянешь, и разложишь по полкам, то тогда это и будет туториал. Сам же сказал, что для новичков, поэтому код нужно обьяснить.
Иначе получается обыкновенный копипаст и ноль приобретенных знаний.

ТО, ЧТО ТЕБЕ КАЖЕТСЯ ЕСТЕСТВЕННЫМ, ДЛЯ ДРУГИХ ТЕМНЫЙ ЛЕС.

Сообщение отредактировал nilrem - Суббота, 08 Августа 2009, 16:41
WXZRWДата: Суббота, 08 Августа 2009, 16:41 | Сообщение # 3
Thousand faces conspiration
Сейчас нет на сайте
Quote (nilrem)
Извини, но это пока не туториал, а просто исходный код с комментариями и ничего больше.
Что такое HDC, HWND, HINSTANCE и т.д.?

ОК, тогда надо будет дописать обьяснения по структурам. Хотя если честно, зарубежные авторы обычно не стесняются назвать туториалом 10 строк для отрисовки кубика на OpenGL =)

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

777OLEKSEY777Дата: Вторник, 11 Августа 2009, 16:35 | Сообщение # 4
Руководитель и 3D дизайнер в IlluGameTea Studio
Сейчас нет на сайте
WXZRW, спасибо. Думаю начинающим программерам пойдет smile
GC-VicДата: Вторник, 11 Августа 2009, 23:57 | Сообщение # 5
GcUp.ru
Сейчас нет на сайте
WXZRW, используй тэг "code". Вот так:

Code
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Dispatch system messages
{
if(msg.message == WM_QUIT) break; // If got WM_QUIT message then break the loop and exit from application

TranslateMessage(&msg); // Otherwise, let's find out what the message is exactly
DispatchMessage(&msg); // And execute it

// Here we culda have an else statement and some stuff inside of it, for example, scene rendering, but we leave
// it as is, 'coz we have nothing to do at this time.


Закон Мерфи: "Если вы уверены, что ваш поступок встретит всеобщее одобрение, кому-то он обязательно не понравится".
WXZRWДата: Четверг, 13 Августа 2009, 14:00 | Сообщение # 6
Thousand faces conspiration
Сейчас нет на сайте
Quote (GC-Vic)
WXZRW, используй тэг "code".

ОК, сегодня попозже обновлю тему.

anisimovДата: Четверг, 13 Августа 2009, 20:21 | Сообщение # 7
старожил
Сейчас нет на сайте
HDC, HWND, HINSTANCE дескрипторы контекста устройства. Характерно для WinApi. HWND дескриптор контекста окна. Вот же сказано.

Первые три вещи это контекст устройства (device context), хендл окна (window handle), и инстанс приложения (application instance)


http://vkontakte.ru/id56359373
Строю Город, обустраиваю Остров. Присоединяйтесь.
WXZRWДата: Четверг, 13 Августа 2009, 21:31 | Сообщение # 8
Thousand faces conspiration
Сейчас нет на сайте
Quote (anisimov)
HDC, HWND, HINSTANCE дескрипторы контекста устройства. Характерно для WinApi. HWND дескриптор контекста окна. Вот же сказано.

Первые три вещи это контекст устройства (device context), хендл окна (window handle), и инстанс приложения (application instance)

Да, теперь все ОК, я уже после того как nilrem обратил на это внимание, дописал данную фразу, до этого я об этом не упоминал, (ну имхо читатели сами в MSDN бы глянули, не проблема).

vergil010Дата: Пятница, 14 Августа 2009, 23:00 | Сообщение # 9
3D master
Сейчас нет на сайте
WXZRW, добавил тэги =) если не сложно, добавляй их сразу, при написаниии статьи.

skype: vergil010
WXZRWДата: Суббота, 15 Августа 2009, 13:58 | Сообщение # 10
Thousand faces conspiration
Сейчас нет на сайте
Quote (vergil010)
WXZRW, добавил тэги =) если не сложно, добавляй их сразу, при написаниии статьи.

ОК, благодарю! Вообще-то думал как выделить код, только вот тега не заметил :) В смысле, до того, как GC-Vic обратил на это мое внинмание. Ну, новый тутор постараюсь оформить в лучшем виде.

vergil010Дата: Суббота, 15 Августа 2009, 15:10 | Сообщение # 11
3D master
Сейчас нет на сайте
WXZRW, ок, будем ждать. Очень интересный тутор!

skype: vergil010
ЖенекДата: Четверг, 15 Июля 2010, 20:24 | Сообщение # 12
частый гость
Сейчас нет на сайте
скачал твой код вставил вот ошибка что у меня не так( код один в один)

Ошибка 1 error C2440: =: невозможно преобразовать 'const char [5]' в 'LPCWSTR'


WXZRWДата: Пятница, 16 Июля 2010, 15:10 | Сообщение # 13
Thousand faces conspiration
Сейчас нет на сайте
Quote (Женек)
скачал твой код вставил вот ошибка что у меня не так( код один в один)

Ошибка 1 error C2440: =: невозможно преобразовать 'const char [5]' в 'LPCWSTR'

Мда, давно уже не был на форуме...

Код компилил на VC++ 6.0 Standard, поэтому на более новых версиях может не компилиться. Впрочем, как я понял, тебе уже в другой теме показали как исправлять эту ошибку.

  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг