Программирование на Visual C++. Архив рассылки - [8]

Шрифт
Интервал

С типами INT, UINT, LONG, ULONG, WORD, DWORD, VOID, SHORT, USHORT, CHAR, FLOAT.  BYTE, BOOL(BOOLEAN), у вас не должно быть никаких проблем, и было бы глупо их тут расписывать. Эти типы дублируют встроенные типы C++, и единственное, на что здесь нужно обращать пристальное внимание — это размер типа. Эти типы рекомендуется использовать вместо встроенных в C++ для улучшения переносимости приложения, т.к. в разных системах встроенные типы имеют различные размеры.

Очень интересен тип WINAPI. По-хорошему это все-таки не тип. Если вы посмотрите в файл windef.h, то увидите следующую строку: "#define WINAPI __stdcall". __stdcall – это ключевое слово языка C++, оно, в частности,  влияет на механизм передачи параметров функции. Суть механизма, определяемого __stdcall состоит в том, что  1) аргументы передаются справа налево; 2) аргументы из стека выбирает вызываемая функция; 3) аргументы передаются по значению (by value), а не по ссылке (by reference), т.е. функции передаются копии переменных; 4) определяет соглашение по декорированию имени функции, т.е. включению в имя дополнительной информации, используемой компоновщиком; 5) регистр символов не изменяется.

То есть оказалось, что WINAPI – это не вовсе тип, а указание о том, что функция использует соглашение __stdcall. Кстати, имейте в виду, что описатель PASCAL и __pascal — это то же самое, что и WINAPI. Но этот описатель является устаревшим, оставлен лишь для совместимости, и Microsoft рекомендует повсеместно использовать вместо него WINAPI.

Использование соглашения __сdecl вместо __stdcall иногда оправданно, но приводит к увеличению размера исполняемого модуля из-за того, что имя функции декорируется в этих соглашениях по-разному.

…продолжение следует…   

ВОПРОС – ОТВЕТ

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

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

Куканов Алексей ([email protected])

A1. А в чем проблема? Внутри, допустим цикла иногда добавляется цикл:

>for( ; GetMessage(lpMsg, hWnd, 0, 0); DispatchMessage(lpmsg));

И для красоты на все "запрещенные" действия ставим флаг (который взводим/гасим по необходимости). Вот и весь велосипед.

Сергей Бойко

Мне вот только не совсем понятно, что значит "иногда добавляется"… Время от времени добавляется, что ли? ;)

A2. Я решил написать ответ на вопрос Куканова Алексея, о корректной прорисовке окна во время какого-то процесса. С MFC это решается элементарно. Пусть есть функция   LRESULT Calculation (LPVOID pParam); Не обращайте внимание на параметры объясню позже. Так вот вместо того чтобы в теле какого-то обработчика запускать эту функцию

>CMyDlg::OnButtonClick() {

> Calculation();

>}

и ждать когда она закончит лучше сделать так 

>CMyDlg::OnButtonClick() {

> AfxBeginThread(Calculation, (LPVOID)m_hWnd,THREAD_PRIORITY_LOWEST);

>}

По сути MFC запускает параллельную нить, которая никак не влияет на перерисовку всего остального. Обычно можно в качестве  pParam передать HWND окна. Потому как узнать когда закончится процесс можно только при помощи сообщений. Например в теле Calculation  

>::SendMessage((HWND)pParam, WM_STOP, 0, 0);

А кто хочет узнать побольше читайте MSDN – "Worker threads".

Alex ([email protected])

Кстати, Alex пишет нам уже второй раз, хочу поблагодарить его за активность.

В принципе такой же, но более обстоятельный ответ на этот вопрос  пришел чуть позже:

A3. Самый оптимальный по-моему способ: Это запустить worker thread – второй поток (если пока только один :)) ) апликации. В качестве параметра передать туда структуру с необходимыми данными, а можно и ничего не передавать. Если все данные хранятся в наследнике CWinApp (дальше – CMyApp) , то получить доступ к объекту апликации можно с помощью функции AfxGetApp(). Единственное замечание по передаче данных из одного потока в другой заключается в том, что надо доступаться ТОЛЬКО к мемберам класса – нельзя вызывать функции класса из другого потока (вернее, можно, если они не изменяют данных класса или не обращаются к оконным функциям класса (относиться к наследникам CWnd)). В итоге имеем схему: 

1. Создается worker thread (поток одной функции, при ее завершении завершается и поток). В качестве параметра функции AfxBeginThread передается указатель на необходимые данные.

2. В основном потоке создается собственное сообщение, сигнализирующее о завершении потока. Оно будет брошено рабочим потоком перед своим завершением с помощью PostMessage (при работе с потоками я предпочитаю PostMessage для обмена такого рода сообщениями, ведь SendMessage ждет завершения работы обработчика события, что часто просто не нужно).

3. Запущенный поток выполняет всю черновую работу, в то время как основной поток апликации занимается важными делами, а именно – ничего не делает, знай крутит себе цикл обработки сообщений и не жужжит.


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Параллельное программирование на С++ в действии. Практика разработки многопоточных программ

В наши дни компьютеры с несколькими многоядерными процессорами стали нормой. Стандарт С++11 языка С++ предоставляет развитую поддержку многопоточности в приложениях. Поэтому, чтобы сохранять конкурентоспособность, вы должны овладеть принципами и приемами их разработки, а также новыми средствами языка, относящимися к параллелизму.Книга «Параллельное программирование на С++ в действии» не предполагает предварительных знаний в этой области. Вдумчиво читая ее, вы научитесь писать надежные и элегантные многопоточные программы на С++11.


Дефрагментация мозга. Софтостроение изнутри

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


Справочник по JavaScript

Вниманию читателей предлагается справочник по JavaScript.Справочник предназначается для людей, уже освоивших азы программирования в JavaScript.Справочник создан на основе информации, предоставленной на сайте «Справочник Web-языков» www.spravkaweb.ru.Дата выхода данной версии справочника: 12:33, 21 марта 2007.


Справочник по PHP

Вниманию читателей предлагается справочник по PHP.Справочник предназначается для людей, уже освоивших азы программирования на языке PHP.Справочник создан на основе информации, предоставленной на сайте «Справочник Web-языков» www.spravkaweb.ru.


Fiction Book Designer Краткое руководство

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