Перейти к содержанию

Лидеры

Популярный контент

Показан контент с высокой репутацией 15.08.2014 во всех областях

  1. /*---------------------------------------------------------------------------*/ 1. Да, например, так. Имя сам задаёшь - главное его же указать при регистрации класса окна. Скажем, класс "окно трейнера". А окон два или три. Значит ты один раз зарегистрировал нужный класс, а окон сделал три, у каждого при этом будет одна и та же оконная процедура. 2. Да, именно так. 3. CreateWindow мы по факту создаём после вызова RegisterClass, просто при этом проверяем, что RegisterClass вернула "1" (или "true"), то есть выполнилась верно. Примерно так: if ( RegisterClass) // Если зарегистрировали класс, то CreateWindow // создаём окно if ( RegisterClass == 1 ) CreateWindow if ( RegisterClass == true ) CreateWindow Второй и третий варианты эквивалентны первому. Это простая проверка, чтобы убедиться что класс зарегистрировался и всё идёт хорошо, так как если произойдёт ошибка, то окно создать не получится. По поводу отладки. Вот картинка:
    2 балла
  2. /*---------------------------------------------------------------------------*/ Итак! Первое, что нужно сделать - это открыть Visual Studio и создать пустой C++ проект. Дальше в него нужно добавить пустой файл исходника и в нём написать нечто такое: #include <windows.h> int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow ) { return 0; } Это - точка входа в приложение. Прямо сейчас она у нас возвращает ноль и программа на этом завершается. Вот картинка, на всякий случай: Идём дальше! Где-то на просторах MSDN мы натыкаемся на функцию [CreateWindow], которая, судя по имени, должна делать окно. Вот её описание: HWND WINAPI CreateWindow( _In_opt_ LPCTSTR lpClassName, _In_opt_ LPCTSTR lpWindowName, _In_ DWORD dwStyle, _In_ int x, _In_ int y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam ); Знает, смотрим на возвращаемый тип. Тип этот - HWND (почитать подробнее про типы данных можно [тут]) - Handle Window - дескриптор (идентификатор) окна. Теперь смотрим на аргументы (in - надо сообщить его фукнции, in_opt - надо сообщить, но не обязательно): LPCTSTR lpClassName - имя какого-то класса (?) LPCTSTR lpWindowName - имя создаваемого окна. DWORD dwStyle - какой-то стиль (??) int x - координаты левого int y - верхнего угла окна int nWidth - ширина окна int nHeight - высота окна HWND hWndParent - дескриптор окна-родителя, в случае если одно окно рожает другое. HMENU hMenu - меню (???) HINSTANCE hInstance - ещё один идентификатор. На этот раз - нашей программы, приехал нам в аргументах в WinMain(). LPVOID lpParam - скучная штука, описывать её не буду. ? - структура, в которой хранится всякая нужная окну фигня, типа иконки, курсора мыши и ещё одной вещи, о которой я напишу в следующем посте. ?? - если коротко, то у окна бывают всякие разные стили. Плоское окно, окно с заголовком, окно с кнопками закрыть-открыть, видимое окно или нет и так далее. ??? - указатель на структуру, описывающую меню окна. Ползём дальше. Функция упрямо требует от нас какой-то класс, которого у нас пока нет. Следовательно, его надо как-то сделать. Идём в гугл и выясняется, что есть функция, которая класс делает (а точнее, регистрирует), и имя ей - [RegisterClass]. Ей надо скормить структуру, описывающую класс окна (всякие важные и полезные для него штуки) и она вернёт "ОК" или "НЕ ОК". Делаем: #include <windows.h> LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) { return DefWindowProc( hwnd, message, wparam, lparam ); } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow ) { WNDCLASS wc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); wc.hCursor = LoadCursor( 0, IDC_ARROW ); wc.hIcon = LoadIcon( 0, IDI_APPLICATION ); wc.hInstance = hInstance; wc.lpfnWndProc = WndProc; wc.lpszClassName = TEXT("Test Window"); wc.lpszMenuName = 0; wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; if (RegisterClass(&wc)) return 1; return 0; } Здесь wc - это структура, описывающая класс окна. Функции RegisterClass мы скармливаем указатель на неё, предварительно заполнив её данными, и сверяем результат с единицей. Если равен, то возвращаем из программы 1, иначе возвращаем 0. Ты наверняка заметил вот эту странную строчку: wc.lpfnWndProc = WndProc; И одноимённую функцию в самом верху. Это - функция окна, в ней будет содержаться вся логика его работы. Подробнее будет дальше. Наконец, создаём окно: if (RegisterClass(&wc)) { HWND hwnd = CreateWindow("Test Window", "Test", WS_VISIBLE | WS_CAPTION | WS_SYSMENU , 0, 0, 640, 480, 0, 0, hInstance, 0); return 1; } Утверждаем, что окно будет класса "Test Window", с именем "Test", видимое, с заголовком и кнопками закрыть-свернуть-развернуть, находиться в верхнем левом углу экрана (0:0) и иметь размеры 640х480 пикселей, без родителя и без меню. Запускаем, проверяем - и ничего не происходит! Отлаживаем код, видим, что hwnd (идентификатор нашего созданного окна) не равняется нулю, значит окно создаётся, видим, что отладчик заходит в функцию самого окна (WndProc), но после этого программа просто завершается. Как так? А легко. Мы забыли о том, как устроены и работают окна. У каждого окна есть процедура, которая что-то делает. Следовательно, ей нужно откуда-то брать данные, чтобы что-то делать. Эти данные называются сообщениями. Скажем, нажали кнопку мыши. Нажали кнопку "закрыть". Нажали клавишу на клавиатуре. И нам нужно каким-то образом научить наше окно принимать и обрабатывать эти сообщения, пока оно не получит сообщение о закрытии. В этом нам поможет функция [GetMessage], которая как раз этим и занимается. Пишем: if (RegisterClass(&wc)) { HWND hwnd = CreateWindow("Test Window", "Test", WS_VISIBLE | WS_CAPTION | WS_SYSMENU, 0, 0, 640, 480, 0, 0, hInstance, 0); MSG msg; while( GetMessage( &msg, 0, 0, 0 ) != 0) { TranslateMessage(&msg); DispatchMessage(&msg); } return 1; } Что тут происходит? После создания окна мы объявили структуру MSG, которая представляет собой пустое сообщение. Дальше мы лезем в бесконечный цикл, в котором принимаем сообщения, а затем запихиваем их в оконную процедуру (WndProc). В оконной процедуре следует написать следующее: LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) { switch( message ) { case WM_DESTROY: PostQuitMessage(0); break; } return DefWindowProc( hwnd, message, wparam, lparam ); } Всякий раз попадая в функцию WndProc, мы получаем в аргументе сообщение. А дальше мы смотрим, что это за сообщение, и реагируем. В частности, выше я описал действие на WM_DESTROY - это когда мы закрываем окно. В ответ на это мы говорим, что пора прощаться, а дальше программа выходит из цикла обработки сообщений и уже тогда завершается. Картинка: Ну как? Получается что-нибудь? Вопросы есть? /*---------------------------------------------------------------------------*/
    2 балла
  3. Бесконечные вещи (использовать на свой страх!!!):
    1 балл
  4. Вот что получилось Risen 3 - Titan Lords CharModer by A1t0r (CT and EXE).rar
    1 балл
  5. Так вот в 8 посте пример О_о Risen докачался, ща ломанём) Указатель на героя [[[Risen3.exe+DD6CC0]+1C]+1С]+X X: +14 - ближний бой +18 - дальний бой +1C - проворность +20 - влияние +24 - выносливость +28 - Ловкость +2C - магия +30 - дух +34 - число+20 = макс. здоровье +38 - здоровье +3C - слава +40 - репутация Скрипт на бессмертие(вариант с записью 100 здоровья):
    1 балл
  6. /*---------------------------------------------------------------------------*/
    1 балл
×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.