Hungry Mind , Blog about everything in IT - C#, Java, C++, .NET, Windows, WinAPI, ...

WinForms button ToolTip bug

Багодром в .NET Framework продолжается. Сегодня обнаружил дефект с ToolTip - после нажатия на кнопку он больше не отображается. Подробнее о проблеме.

Решение - в обработчике нажатия устанавливать ToolTip заново.

In Search Of Sunrise 7 FLAC

In search of sunrise 7

11+10+9+8+7+6+5+4+3+2+1

ReSharper 4.0 is released

Greetings from JetBrains!

We are pleased to announce the general availability of ReSharper 4.0!

This release brings you the most up-to-date support for C# 3.0, including LINQ, and Visual Studio 2008 in general. The major upgrade also features multiple new usability and productivity-boosting tools, such as standard class library annotations, solution-wide analysis (for C#), versatile code cleanup, new automated refactorings, new and improved code-editing capabilities, and more.

Complete product information about JetBrains ReSharper is available at http://www.jetbrains.com/resharper.

ReSharper 4.0 is available for a 30-day free trial download at http://www.jetbrains.com/resharper/download. No evaluation licenses are required.

New customers can purchase ReSharper 4.0 online at http://www.jetbrains.com/resharper/buy.

Please NOTE: All those who have purchased ReSharper 3.0 or ReSharper 3.1 after December 21, 2007 qualify for a free upgrade!

Wishing you develop with pleasure!! Team JetBrains

Silverlight Tools Beta 2 for Visual Studio 2008

Download Microsoft Silverlight Tools Beta 2 for Visual Studio 2008.

Download Expression Blend 2.5 June Preview.

InstallShield 2009 released

Precompiled Headers Explained

Почти все разработчики, использующие Visual C++, сталкиваются с файлом stdafx.h, в который можно положить много-много различных директив препроцессора. И так мало понимают, зачем это нужно и как с этим работать...

Precompiled Header

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

Рассмотрим программу Hello World:

#include <tchar.h>
#include <iostream>

int _tmain(int argc, _TCHAR* argv[]) {
    std::cout << "Hello World!" << std::endl;
    return 0;
}

А теперь внимание: после обработки этого файла прекомпилятором, его размер возрастает до 996 килобайт! Я повторюсь: 996 килобайт, из которых 854 составляют полезный код (остальное - комментарии), а размер рабочего кода программы - аж 142 байта. Похоже, для компиляции нашего простейшего cpp-файла компилятору прийдется изрядно потрудиться. Причем над каждым cpp-файлом проекта.

Естественно, лучше предварительно обработать неизменящиеся куски кода, превратив их в удобный и быстрый формат для последующей обработки в составе исходного кода приложения. Компиляторы Visual C++ и GCC поддерживают такую обработку и она носит имя Precompiled Header.

Использование Precompiled Header в Visual C++

Мастер создания проекта Visual C++ предлагает свои услуги по настройке Precompiled Header. В простейшем случае, среда дает разработчику возможность выбора - использовать этот механизм или нет. В большинстве случаев использование Precompiled Header настраивается автоматически.

Анализ настроек Precompiled Header мастеров Visual C++

Что же мы получаем при автоматической настройке Precompiled Header средой разработки Visual Studio?

  1. Заголовочный файл stdafx.h

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

  2. cpp-файл stdafx.cpp

    Состоит из единственной директивы #include "stdafx.h" и используется для генерации Precompiled Header. Следующая картинка демонстрирует свойства файла stdafx.cpp, раздел C/C++, подраздел Precompiled Headers:stdafx.cpp Property Pages

  3. Каждый cpp-файл проекта, использующий Precompiled Header, обязан включать этот заголовочный файл соответствующей директивой #include "stdafx.h"

    При этом компилятор игнорирует любой текст до момента включения stdafx.h! А в случае его отсутствия - выдает ошибку fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?

  4. Использование Precompiled Header установлено на уровне cpp-файлов всего проекта, как показано на картинке:

    Project Property Pages

Настройка Precompiled Header вручную

Опираясь на вышенаписанное, последовательность действий простая:

  1. Создать файл CommonIncludes.h
  2. Создать файл CommonIncludes.cpp и добавить туда одну строчку - #include "CommonIncludes.h"
  3. Поменять нужные настройки Precompiled Headers в свойствах файла CommonIncludes.cpp
  4. Поменять настройки Precompiled Headers на уровне проекта или на уровне отдельных cpp-файлов
  5. Добавить #include "CommonIncludes.h" в начало соответствующих cpp-файлов исходного кода

Продвинутое использование Precompiled Header

Как правило, в stdafx.h, созданный визардом, лепят все, что можно влепить. В результате в каждый cpp-файл включается совершенно ненужный ему контент! Поэтому, логично включать в stdafx.h только наиболее используемые заголовочные файлы.

Директивы прекомпилятора в stdafx.h распостраняются одинаковым образом на все cpp-файлы, включающие данный заголовочный файл. Бывает, необходимо настроить поведение библиотеки (в рамках отдельного cpp-файла или группы таких файлов) путем определения каких-то символов перед включением соответствующего заголовочного файла. Первое, что приходит на ум, - определить эти символы в cpp-файле и еще раз включить заголовочный файо библиотеки. Но, нет, я же писал, что компилятор игнорирует любой исходный код до строчки #include "stdafx.h"! Соответственно, повторное включение заголовочных файлов будет просто проигнорировано. Получается, нужно удалять включения заголовочных файлов библиотек из stdafx.h и добавлять их в каждый отдельный cpp-файл.

Также, проект не ограничен одним Precompiled Header! Вполне можно содзать пару файлов Subsystem1Includes.h, Subsystem1Includes.cpp, отвечающих за отдельный Precompiled Header в рамках некоторой группы файлов исходного кода.

Компилятор Visual C++ имеет ограничение на размер pch-файла. На практике это выглядит следующим образом:

error C3859: virtual memory range for PCH exceeded; please recompile with a command line option of '-Zm130' or greater
fatal error C1076: compiler limit : internal heap limit reached; use /Zm to specify a higher limit

В таком случае спасет опция компилятора /Zm: /Zm compiler option

Copyright 2007-2011 Chabster