Порядок подключаемых либ в Code::Blocks

Сегодня я столкнуля с одной странной вещью. Вернее, я уже сталкивался с этим, но как-то подзабыл уже. Суть в следующем. Я обычно использую среду разработки Code::Blocks. Итак у меня была уже созданная мной статическая либа — назовем ее Lib1. Сегодня я создал либу (назовем ее Lib2), которая использует функции из либы Lib1. Сегодня же я попытался собрать небольшое консольное приложение (назовем его Test), которое использует класс из либы Lib2. Явно приложение Test не вызывает ничего из либы Lib1. Но  в проекте Test все равно надо прописать все используемые либы, поскольку при создании статической либы другие используемые ею статические либы не линкуются к ней. Итак я прописал либы так:

Lib1

Lib2

Компоновщик сыпал сообщениями «undefined reference to …», где вместо многоточия были названия функций из либы Lib1. «Что за фак?» — подумал я, ведь либы подключены. По мере течения времени, затрачиваемого на поиск причины этого бага, я начинал произносить фразы, описывающее мое отношение к этой ситуации, в более жесткой форме.

Я попробовал явно вызвать одну из функций либы Lib1 в main(). Надо же! Проект Test собирается. Ладно. Я создаю в либе Lib1 специальную пустую функцию, думая, что в Test нужно вызвать любую функцию из либы Lib1 явно. Но какого … Проект Test опять не собирается. Я перезагрузил комп, думая, что дело в засоре оперативной памяти…

После очередной порции выплюнутых линкером ругательств, до моего сознания начали доноситься смутные воспоминания о том, что я менял порядок либ, когда проблема возникла в прошлый раз. Я взял и поменял либы в настройках проекта:

Lib2

Lib1

Охренеть! Проект собрался. Да. Это что-то совсем странное. Вообщем, я пока не планирую менять среду разработки — довольно длительное время я вполне эффективно работал в ней и особых багов не возникало. Но решил сообщить об этом в блоге. Да и самому пригодится, думаю. Если позабуду.

WinAPI. Перемещение и изменение размеров окна

Сегодня я поделюсь демкой, которая демонстрирует как приходят сообщения при изменении размеров и при перемещении окна. Там же есть несколько контрольных вопросов. Обратите внимание на то, в какой системе координат и какие параметры передаются вместе с сообщениями WM_SIZE и WM_MOVE. Также я добавил меню, в котором можно управлять перемещением окна и его размерами. Все операции завязаны на использовании функции MoveWindow.

Демка с исходниками

Контроль знаний по WinAPI

Привет всем, кто волею случая наткнулся на этот блог. Этой статьей я начинаю цикл публикаций, смыслом которого будет заключаться в самоконтроле знаний по WinAPI. Дело в том, что по WinAPI существуют достаточно хорошие книги и все там прекрасно разжевано (книги Петцольда, Щупака, Ганеева, Рихтера, библиотека братьев Фроловых). Чтива навалом, короче. Поэтому, я их содержание повторять здесь не буду. Также я не буду заниматься такой глупой и безнадежной вещью, как объяснение того, зачем нужно изучать WinAPI — это каждый решает для себя сам.

Что я здесь буду описывать и для чего?

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

Многие базовые вещи в WinAPI встречаются настолько часто, что проще их заучить, чем постоянно лазить за справкой в MSDN. Разработка, при которой вам нужно лезть в MSDN, чтобы посмотреть прототип каждой функции или структуры,  — это кошмарно медленно и неэффективно.

Итак, начну я с такой банальной вещи как создание простого оконного приложения.

Простое оконное приложение под Windows

1. Напечатайте прототип функции «WinMain». Расскажите об ее параметрах.
2. Что такое класс окна? Зачем он нужен?
Напечатайте прототип и расскажите о смысле параметров функции «RegisterClassEx».
3. Что возвращает функция «RegisterClassEx» в случае ошибки?
4. Напечатайте список членов класса «WNDCLASSEX» и опишите их.
5. Какие идентификаторы стиля класса окна обеспечивают его автоматическую
перерисовку при изменении размеров окна?
6. Как задать в классе окна стандартную иконку?
7. Как задать в классе окна стандартный курсор-стрелку?
8. Как задать в классе окна цвет кисти фона (например, белый)?
9. Напечатайте прототип функции «CreateWindow». Что она возвращает в случае ошибки?
10. Напечатайте стиль перекрывающегося окна.
11. Как задать параметры x,y,nWidth, nHeight по умолчанию?
12. Как вывести созданное окно на экран? Приведите пример и опишите функцию.
13. Приведите пример простейшего цикла сообщений приложения. Расскажите как он работает.
14. Напечатайте прототип функции «GetMessage». Опишите параметры и смысл возвращаемых значений.
15. В чем опасность этого цикла:

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

// ? приведите правильный вариант.
16. Напечатайте прототип функции TranslateMessage. Опишите, что она делает.
17. Что делает функция DispatchMessage и какие у нее параметры?
18. Напечатайте прототип функции обработчика сообщений окна.
19. Напечатайте минимальный обработчик сообщений окна.

Тестовое задание — написать приложение windows с одним простым окном, не пользуясь никакими справочниками.

 

Ответы и решения*:
5.  Ответ: CS_HREDRAW, CS_VREDRAW.

6. Решение:
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

7. Решение:
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

8. Решение:
wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);

10.  Ответ: WS_OVERLAPPEDWINDOW.

11. Ответ: передать константу CW_USEDEFAULT.

12.  Решение:
ShowWindow(hwnd, SW_SHOWNORMAL);

15. Решение:
MSG msg;
BOOL bRet;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0 )
{
if (bRet == -1)
{
// Обработка ошибки, выход
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

19. Решение:

LRESULT CALLBACK

WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

Пример выполнения тестового задания: BaseWindow1


 

Там, где я не указал ответов, они либо устные либо нужно смотреть в MSDN/книгу.