Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Начинающим


Автор: Fixin 25.8.2005, 20:38
Windows API.
Введение.
Это не книга, не учебник. Это статья, призванная помочь Вам в изучении Windows API на языке C/C++, но не учит языку. Многие программы написаны с использованием макросов, описанных в заголовочном файле <WindowsX.h>.
Начало.
Многие, начинающие изучать API (application programming interface – интерфейс программирования приложений), удивляются объему кода, сложности и тп, говорят, что проще сделать в Borlan® Builder®. Если Вы так думаете, то зачем читаете этот текст?
Вы еще здесь? Тогда продолжим серьезно и без лени.
Вот простейший код:
Код 1.0+NoWindow.cpp+------------------------------------------------
Код

#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    MessageBox(NULL, "Сказала собака баскервилей.", "Ну, здравствуй, Герасим.", MB_OK|MB_ICONEXCLAMATION);
    return 0;
}

Код 1.0+NoWindow.cpp+------------------------------------------------Конец
Что за прараметры?
Начнем с параметров главной функции. Кстати, это САМАЯ главная функция. Функция WndProc (о которой позже) является главной оконной процедурой.
Итак, параметры… HINSTANCE вообще интересный тип. Это своего рода дескриптор объекта (HANDLE).
В первом случае (hInstance) он указывает на тот исполняемый модуль, на основе которого запущен процесс данного кода. Проще говоря, указывает на файл “NoWindow.exe”.
Второй параметр (hPrevInstance) – пережиток Win16. В 32-разрядных приложениях не используется. Раньше обозначал предыдущий запущенный экземпляр данного приложения. Если не ноль, значит Бог есть! Однозначно.
Третий (lpszCmdParam) – строка параметров, которые были посланы программе при запуске. Если их не было, то строка пуста.
Четвертый (nCmdShow) – число, обозначающее вид окна при запуске. Например, свернутое, развернутое, нормальное.
Если решили изменить состояние окна во время выполнения приложения, то это сообщение посылается в окно функцией ShowWindow, например так:
Код

ShowWindow(hwnd, SW_SHOWMINIMIZED);


За одно, разберем параметры вызова MessageBox.
Первый – дескриптор окна, к которому принадлежит сообщение. Это нужно для того, что бы Windows знала, какое окно его вызвало и, соответственно, сделать его неактивным, пока вы не ответите в нем нажатием какой-нибудь кнопки.
Второй и третий – строки. Соответственно, текста сообщения и текста заголовка сообщения.
Четвертый – самый интересный. В нем указывается стиль сообщения. Они находятся в файле <WinUser.h>. Смотрите MSDN.
Делаем окно.
Начнем сразу с кода:
Код 2.0+SimWnd.cpp+------------------------------------------------
Код

#include <windows.h>
#include <windowsx.h>

#define SimWnd_DefProc DefWindowProc
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL Register(HINSTANCE hInstance);
HWND Create(HINSTANCE hInstance, int nCmdShow);

static char szAppName[] = "SimWnd";
static HWND hMainWindow;

void SimWnd_OnDestroy(HWND hwnd);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpszCmdParam, int nCmdShow)
{
    MSG Msg;

    if (!Register(hInstance))
            return FALSE;    
    if (!Create(hInstance, nCmdShow))
            return FALSE;

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

    return Msg.wParam;
}

BOOL Register(HINSTANCE hInstance)
{
    WNDCLASS WndClass;
        
    WndClass.style            =    CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc    =    WndProc;
    WndClass.cbClsExtra        =    0;
    WndClass.cbWndExtra        =    0;
    WndClass.hInstance        =    hInstance;
    WndClass.hIcon            =    LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor        =    LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground    =    (HBRUSH)(COLOR_BTNFACE+1);
    WndClass.lpszMenuName    =    NULL;
    WndClass.lpszClassName    =    szAppName;

    return (RegisterClass(&WndClass) != 0);
}

HWND Create(HINSTANCE hInstance, int nCmdShow)
{
    HWND hwnd = CreateWindow(szAppName, szAppName,
                    WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    NULL, NULL, hInstance, NULL);

    if (hwnd == NULL)
        return FALSE;

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    return hwnd;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message,
                         WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
        HANDLE_MSG(hwnd, WM_DESTROY, SimWnd_OnDestroy);        
        default:
            return SimWnd_DefProc(hwnd, Message, wParam, lParam);
    }    
}

void SimWnd_OnDestroy(HWND hwnd)
{
    PostQuitMessage(0);
}

Код 2.0+SimWnd.cpp+------------------------------------------------Конец

Разбор полетов.
Не маленький код . Но не надо бояться – этот код копируется из приложения в приложение и не надо его учить наизусть (хотя, если есть желание…).
Итак, посмотрим. Три шага создания окна:
1) Регистрация. (Register())
2) Создание. (Create())
3) Обработка сообщений. (WndProc())
Когда мы создаем оконное приложение, мы как бы делаем подкласс объекта «окно» благодаря этим трем шагам. Поясню. При создании кнопки (класс “button”) , регистрацию и обработку сообщений выполняет система, а создание – программист. Программист также может создать свой класс кнопки и сделать ей любые свойства такие, как подсветка или градиент. Но об этом когда-нибудь потом.
При регистрации, мы сообщаем системе, в основном, название нового класса и процедуру обработки его сообщений, ну и некоторые элементы внешнего вида и другие параметры.
Создание окна – тут все просто. Вызов функции CreateWindow(). А при создании нового окна, после этой вызываются ShowWindow() и UpdateWindow(). Они призваны соответственно показать и обновить окно.
Самое сложное и обычно наиболее емкое по коды – это обработка сообщений. Есть такая штука – DefWindowProc – стандартная оконная процедура. Все наше окно полностью работает за счет этой процедуры. Только я поступил так, как делают многие программисты:
Код

#define SimWnd_DefProc DefWindowProc

Просто дал ей свое название. Единственное сообщение, которое она не обрабатывает, это WM_DESTROY – сообщение о закрытии окна. Если его не обрабатывать, то окна видно не будет, но процесс так и останется. Не очень удобно.
Сообщения.
Все функционирование в Windows основано на сообщениях. Даже то, что вы передвигаете мышь. Точнее её перерисовка. А как их получает оконная процедура? Все начинается тут:
Код

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

А продолжается тут:
Код

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message,
                         WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
        HANDLE_MSG(hwnd, WM_DESTROY, SimWnd_OnDestroy);        
        default:
            return SimWnd_DefProc(hwnd, Message, wParam, lParam);
    }    
}

Функция GetMessage получает сообщение от системы и пересылает его оконной процедуре. Там программист обрабатывает его так, как хочет. Если он этого не делает или ему этого не нужно, то оно обрабатывается стандартной процедурой. Сообщений очень много и приводить их здесь нецелесообразно – займет пару страниц. Скажу только то, что когда я не знал, как называется сообщение, то открывал файл <WinUser.h> искал WM_NULL и смотрел далее сообщения, а по названию определял назначение, далее по справке и, в конце-концов, можно найти.
Рассмотрим параметры в функции WndProc:
1) Дескриптор окна, к которому относится сообщение.
2) Само сообщение.
3) Параметр сообщения.
4) Параметр сообщения.
Зачем два одинаковых параметра? Во-первых, не совсем одинаковые, а во-вторых смотрим: один параметр – 32 бита и второй 32. Очень многое можно указать в 64 битах, да еще 4 с лишним миллиарда возможных сообщений. Перейдем к практическим занятиям.
Делаем кнопки!
Код 2.1+SimWnd.cpp+------------------------------------------------
Код

#include <windows.h>
#include <windowsx.h>

#define SimWnd_DefProc DefWindowProc
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL Register(HINSTANCE hInstance);
HWND Create(HINSTANCE hInstance, int nCmdShow);

static char szAppName[] = "SimWnd";
static HWND hMainWindow;

void SimWnd_OnDestroy(HWND hwnd);
BOOL SimWnd_OnCreate(HWND hwnd, CREATESTRUCT* pCreateStruct);
void SimWnd_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);

#define BT_FIRSTBUTTON 10001

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpszCmdParam, int nCmdShow)
{
    MSG Msg;

    if (!Register(hInstance))
            return FALSE;    
    if (!Create(hInstance, nCmdShow))
            return FALSE;

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

    return Msg.wParam;
}

BOOL Register(HINSTANCE hInstance)
{
    WNDCLASS WndClass;
        
    WndClass.style            =    CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc    =    WndProc;
    WndClass.cbClsExtra        =    0;
    WndClass.cbWndExtra        =    0;
    WndClass.hInstance        =    hInstance;
    WndClass.hIcon            =    LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor        =    LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground    =    (HBRUSH)(COLOR_BTNFACE+1);
    WndClass.lpszMenuName    =    NULL;
    WndClass.lpszClassName    =    szAppName;

    return (RegisterClass(&WndClass) != 0);
}

HWND Create(HINSTANCE hInstance, int nCmdShow)
{
    HWND hwnd = CreateWindow(szAppName, szAppName,
                    WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    NULL, NULL, hInstance, NULL);

    if (hwnd == NULL)
        return FALSE;

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    return hwnd;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message,
                         WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
        HANDLE_MSG(hwnd, WM_DESTROY, SimWnd_OnDestroy);
        HANDLE_MSG(hwnd, WM_CREATE, SimWnd_OnCreate);
        HANDLE_MSG(hwnd, WM_COMMAND, SimWnd_OnCommand);
        default:
            return SimWnd_DefProc(hwnd, Message, wParam, lParam);
    }    
}

void SimWnd_OnDestroy(HWND hwnd)
{
    PostQuitMessage(0);
}

BOOL SimWnd_OnCreate(HWND hwnd, CREATESTRUCT* pCreateStruct)
{
    CreateWindow("button", "Кнопка", WS_CHILD|WS_VISIBLE,
        10, 10, 90, 25, hwnd, 
        HMENU(BT_FIRSTBUTTON), 
        pCreateStruct->hInstance, NULL);
    return TRUE;
}

void SimWnd_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
    switch (id)
    {
        case BT_FIRSTBUTTON:
            MessageBox(hwnd, "Ё-моё!", "Работает,", MB_OK|MB_ICONEXCLAMATION);
            break;
    }
}

Код 2.1+SimWnd.cpp+------------------------------------------------Конец
У Вас мог возникнуть вопрос, как узнать сигнатуру функций обработки сообщений. Просто. В файле <WindowsX.h> есть такой шаблон Cls_OnXXXXX. То есть, если нам нужен обработчик сообщения WM_COMMAND, то ищем Cls_OnCommand и смотрим сигнатуру.
Разбор полетов.
В этом коде мы использовали два новых сообщения: WM_CREATE и WM_COMMAND. Первое программист использует для задания «предпусковых» установок и создания динамических элементов управления. В нашем примере был употреблен второй случай – создание кнопки.
WM_COMMAND призвано реагировать на команды программе, в основном, от элементов управления. Например, на нажатие кнопки.
Заметьте, что объем кода 2.1 не многим больше, чем в 2.0. Об этом я и говорил в начале, что основная часть кода копируется из приложения в приложение.
В обработчике OnCreate вызывается функция CreateWindow, вот ее параметры:
1) Символьное название класса.
2) Название элемента или текс в новом элементе.
3) Стиль окна. Их много…
4,5,6,7) Координаты x, y, dx, dy.
8) Дескриптор окна-родителя.
9) Дескриптор меню или идентификатор элемента.
10) Дескриптор модуля.
11) Указатель на значение, которое будет послано в структуре CREATESTRUCT.
В основном, этот обработчик используется для загрузки настроек, ресурсов, подключения динамических библиотек и т. п.
Обработчик OnCommand имеет менее разнообразное назначение (хотя, кто знает, что можно выдумать…). Этот обработчик получает четыре параметра – дескриптор главного окна, идентификатор элемента, дескриптор этого элемента и дополнительная информация. В последнем примере обрабатывается идентификатор кнопки, который задается 9-м параметром функции CreateWindow, в котором указывается целое число, преобразованное с помощью HMENU. А пример достаточно полно показывает «способ употребления» этого обработчика.

В файле тот же текст, но в формате "doc".
Остаюсь без компьютера (еду в инст). Статью писал наскоро, потому прошу модераторов редактировать недостатки, сообщаяя о них на ПМ.



Автор: Fixin 25.8.2005, 20:39
А файл вот:

Автор: ShadowPhoenix 15.6.2006, 17:55
По поводу первой програмки... попробовал откомпилировать в MVS2005  и получил такую козу:
Код

------ Build started: Project: simple, Configuration: Debug Win32 ------
Compiling...
code.cpp
z:\prog\vc\first mfc program\simple\simple\code.cpp(5) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [29]' to 'LPCWSTR'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Build log was saved at "file://\\fdoserv\общий доступ\Prog\VC\First MFC program\simple\simple\Debug\BuildLog.htm"
simple - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

 что я тут не понял:
 1. С какого перепугу "MessageBoxW" вместо "MessageBox", в MSDN такой фишки вообще нет... ну это ладно.
 2. поповоду самого "MessageBox"
в MSDN :
Код

Syntax

int MessageBox
(         
           HWND hWnd,
           LPCTSTR lpText,
           LPCTSTR lpCaption,
           UINT uType
);


Parameters

-hWnd
  [in] Handle to the owner window of the message box to be created. If this parameter is NULL, the       message box has no owner window. 
-lpText
  [in] Pointer to a null-terminated string that contains the message to be displayed. 
-lpCaption
  [in] Pointer to a null-terminated string that contains the dialog box title. If this parameter is NULL, the -default title Error is used. 
-uType
  [in] Specifies the contents and behavior of the dialog box. This parameter can be a combination of flags from the following groups of flags.


т.е. по логике вещей должно приводиться??? или я чего не так понимаю.
далее начал химичить пытаясь его запустить хоть как-то... и пришел к такому вот обрезаному виду:
Код
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    LPCWSTR s1,s2;
    MessageBox(NULL, NULL, NULL, MB_OK|MB_ICONEXCLAMATION);
    return 0;
}


 smile так собственно сам вопрос как строку  к этому страшному LPСWSTR приводить... перепробовал все известные мне способы smile , из знакомых никто не знает smile
  

Автор: Earnest 15.6.2006, 18:32
Цитата(ShadowPhoenix @  15.6.2006,  18:55 Найти цитируемый пост)
С какого перепугу "MessageBoxW" вместо "MessageBox", в MSDN такой фишки вообще нет... 

Очень многие имена API, которые описаны в MSDN, есть не функции, а макросы. К ним, в частности, относится и MessageBox. На самом деле есть 2 различных ф-и: MessageBoxA и MessageBoxW. Первая используется, если приложение работает с ANSI-строками, второе - с UNICODE. Соответственно, MessageBox - это либо MessageBoxA, либо MessageBoxW.
Теперь о перепуге.
Неизвестно, с какого перепуга, но начиная с VC 2005, проект по умолчанию генерится как UNICODE. А мужики-то не знают... Сколько уже несчастных новичков на эти грабли наступило. Тебе всего лишь надо свои строки заменить их широкими аналогами. Т.е. добавить L перед кавычками (L"XXX").
Есть способ сделать код независимым от типа используемых символов: 
1) заворачивать все строки в макрос _T: _T("XXX") 
2) всегда использовать t-аналоги CRT-функций: не strlen, а _tcslen, и т.д.
3) использовать типы TCHAR, LPTSTR вместо char, LPSTR...

Теперь ты знаешь, что твое приложение настроено на UNICODE
 smile   

Автор: maxim1000 15.6.2006, 18:32
ShadowPhoenix, возможно, эта тема будет полезна:
http://forum.vingrad.ru/index.php?showtopic=98640&hl=messagebox 

Автор: 0x07L 15.6.2006, 19:10
Конечно, я здесь далеко не самый умный, но попытаюсь тебе помочь.

MessageBox, CreateWindow и еще много функций, которые ты встретишь в MSDN - это макросы вида

#ifdef _UNICODE
#define SomeFunction(...) SomeFunctionW (...)
#else
#define SomeFunction(...) SomeFunctionA (...)
#endif

Открой WinUser.h и найдешь там множество таких конструкций (в т.ч. и для MessageBox).
Суть конструкций в следующем: если где-нибудь в проекте объявлен _UNICODE
(это можно сделать с помощью директивы препроцессора #define или установить в свойствах проекта),
то препроцессор (специальная вещь, обрабатывающая твой исходный код перед тем, как последний попадет в компилятор)
заменяет вызовы функции SomeFunction на вызовы функции SomeFunctionW.
Если _UNICODE не объявлен, подставляется вызов функции SomeFunctionA (A значит ANSI).

Так в сообщении об ошибках появился MessageBoxW. Именно MessageBoxW, а не MessageBoxA, поскольку в 2005ой Студии Юникод по умолчанию включен. Если он тебе не нужен, его можно отключить в свойствах проекта, и никаких ошибок при компиляции примера у тебя не будет (будет, правда, пара предупреждений о том, что ты злонамеренно отключил Юникод).

Зачем нужен этот Юникод? Дело в том, что обычно текстовые символы кодируются значениями от 0 до 255, занимающими 1 байт. Естественно, что 256 символов недостаточно, чтобы закодировать символы всех национальных алфавитов. На наших с тобой компьютерах русские символы кодируются значениями где-то в интервале 128..255. В индийских, для примера, версиях винды такие же коды будут соответствовать совсем другим символам. Таким образом, у разработчика слишком мало возможностей для локализации своего продукта.

Для того чтобы дать разработчику такие возможности, и был придуман Юникод, в котором каждый символ кодируется двумя байтами (на самом деле все несколько сложнее, но в общем дело обстоит именно так). Для того чтобы обеспечить поддержку Юникода, в заголовочных файлах windows.h и tchar.h объявлено несколько полезных типов данных и макросов.

Во-первых, чтобы все строковые литералы, которые имеются в твоей программе, нужно пометить как "юникодовые". Ставишь перед ними букву L.

"Сказала собака баскервилей." -> L"Сказала собака баскервилей."

Есть полезный макрос _TEXT("..."), чтобы подставлять букву L, когда объявлен _UNICODE.

"Сказала собака баскервилей." -> _TEXT("Сказала собака баскервилей.")

Во-вторых, пометить нужно и символьные константы. Делать это проще всего с помощью макроса _T.

'Ю' -> _T('Ю')

В-третьих, вместо char нужно использовать wchar_t, а лучше макрос TCHAR.

char a; -> TCHAR a;

В-четвертых, указатели на char не забудь поменять на указатели на TCHAR, они же LPTSTR.

char * MyString; -> TCHAR * MyString = LPTSTR MyString.

Что такое LPCWSTR и прочие LP...STR, можно узнать в MSDN (ищи Windows Data Types).
Вот в принципе, и все.

Внимание! Макрос TCHAR объявлен в tchar.h. Подключи его #include <tchar.h> 

  

Автор: ShadowPhoenix 16.6.2006, 11:42
понял, въехал и разобрался... а вообще по науськаванию комнилятора перешел на класс wchar_t ... пока все работает  smile ... А потом просто перешел на ANSI...

Всех благодря за помощь и понимание smile

Автор: ShadowPhoenix 16.6.2006, 17:06
 smile Хм... возник еще один вопрос... уже по HANDLE_MSG, точнее по тому откуда он берет параметры...

ну в данном случае
Код
 HANDLE_MSG(hwnd, WM_DESTROY, SimWnd_OnDestroy);

можно заменить на 
Код
case WM_DESTROY:
        SimWnd_OnDestroy(hwnd);    
        break;

а вот дальше... Совершенно непонятно откуда береться параметр pCreateStruct при вызове
Код
SimWnd_OnCreate(HWND hwnd, CREATESTRUCT* pCreateStruct)

так же хотелось бы получить комментарии к параметрам функции
Код
SimWnd_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)

попробовал изменить
Код
  HANDLE_MSG(hwnd, WM_COMMAND, SimWnd_OnCommand);

на
Код

    case BT_FIRSTBUTTON:
            MessageBox(hwnd, "Ё-моё!", "Работает,", MB_OK|MB_ICONEXCLAMATION);
            break;
...и не работает  smile -  smile тогда что такое id??? непонял 
PS. Вначале думал http://forum.vingrad.ru/index.php?showtopic=60776&hl=handle_msg тему оставить, но тут вопросов по приведённому тексту всетки больше     

Автор: 0x07L 16.6.2006, 19:08
2_ShadowPhoenix

Пользуйся поиском. В WindowsX.h:

#define HANDLE_MSG(hwnd, message, fn)    \
    case (message): return HANDLE_##message((hwnd), (wParam), (lParam), (fn))

Здесь вместо HANDLE_MSG в зависимости от message подставляется другой макрос
(HANDLE_WM_CREATE для WM_CREATE, HANDLE_WM_COMMAND для WM_COMMAND)

В том же WindowsX.h (немного ниже):

#define HANDLE_WM_CREATE(hwnd, wParam, lParam, fn) \
    ((fn)((hwnd), (LPCREATESTRUCT)(lParam)) ? 0L : (LRESULT)-1L)

LPCREATESTRUCT - это есть то же самое, что CREATESTRUCT *
Вот откуда CREATESTRUCT

В WindowsX.h:

#define HANDLE_WM_COMMAND(hwnd, wParam, lParam, fn) \
    ((fn)((hwnd), (int)(LOWORD(wParam)), (HWND)(lParam), (UINT)HIWORD(wParam)), 0L)

id - это LOWORD(wParam)

Для того чтобы разобраться в этих макросах, посмотри в MSDN описание сообщений WM_CREATE и WM_COMMAND.

PS Кстати, воспользуясь случаем, порекомендую книжку Румянцева "Азбука программирование в Win32 API" (вроде так)
Хорошая книжка для начинающих. 

Автор: ShadowPhoenix 17.6.2006, 14:19
0x07L, благодарю за книгу...

Если кого заинтересует, то качать можно http://djvu.504.com1.ru:8019/WWW/42166f7aa576e3bf6786a4cb0052415a.djvu...

мне покачто нравиться smile 

Автор: Dmitry_177 12.10.2006, 11:47
Я новичек в Visual C++, решил слезть с Delphi и писать на VC++. Подскажите пожалуйста, как создавать API-приложения VC++? Создаю я новый проект "Win32 Project", потом на сколько я понимаю "stdafx.h" не нужен для написания программ на чистом API, то я его удаляю и в Solution Explorer-е тоже, там еще и "stdafx.cpp".. потом удаляю всю заготовку кода и пишу следующее:

Код

#include <windows.h>
#include <windowsx.h>

#define SimWnd_DefProc DefWindowProc
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
BOOL Register(HINSTANCE hInstance);
HWND Create(HINSTANCE hInstance, int nCmdShow);

static char szAppName[] = "SimWnd";
static HWND hMainWindow;

void SimWnd_OnDestroy(HWND hwnd);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpszCmdParam, int nCmdShow)
{
    MSG Msg;

    if (!Register(hInstance))
            return FALSE;    
    if (!Create(hInstance, nCmdShow))
            return FALSE;

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

    return Msg.wParam;
}

BOOL Register(HINSTANCE hInstance)
{
    WNDCLASS WndClass;
        
    WndClass.style            =    CS_HREDRAW | CS_VREDRAW;
    WndClass.lpfnWndProc    =    WndProc;
    WndClass.cbClsExtra        =    0;
    WndClass.cbWndExtra        =    0;
    WndClass.hInstance        =    hInstance;
    WndClass.hIcon            =    LoadIcon(NULL, IDI_APPLICATION);
    WndClass.hCursor        =    LoadCursor(NULL, IDC_ARROW);
    WndClass.hbrBackground    =    (HBRUSH)(COLOR_BTNFACE+1);
    WndClass.lpszMenuName    =    NULL;
    WndClass.lpszClassName    =    szAppName;

    return (RegisterClass(&WndClass) != 0);
}

HWND Create(HINSTANCE hInstance, int nCmdShow)
{
    HWND hwnd = CreateWindow(szAppName, szAppName,
                    WS_OVERLAPPEDWINDOW,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    CW_USEDEFAULT, CW_USEDEFAULT,
                    NULL, NULL, hInstance, NULL);

    if (hwnd == NULL)
        return FALSE;

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    return hwnd;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT Message,
                         WPARAM wParam, LPARAM lParam)
{
    switch (Message)
    {
        HANDLE_MSG(hwnd, WM_DESTROY, SimWnd_OnDestroy);        
        default:
            return SimWnd_DefProc(hwnd, Message, wParam, lParam);
    }    
}

void SimWnd_OnDestroy(HWND hwnd)
{
    PostQuitMessage(0);
}


Возникает такое сообщение "c:\apiwindow\apiwindow.cpp(83) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
 И exe-файл не создается... Что делать? Нужен ли этот stdafx и как с ним обходиться?

Автор: maxim1000 12.10.2006, 11:55
stdafx используется для прекомпилированных заголовков, это не зависит от использования WinAPI (насколько я знаю)
при создании проекта в VC++2005 можно снять галочку "Precompiled headers", в двургих версиях - не помню...

Автор: Dmitry_177 12.10.2006, 12:18
У меня тоже VS2005 убрал я "Precompiled headers" только я не увидел там галочки, а выбрал из списка "Not Using Precompiled Headers" в параметре "Create/Use Precompiled Header".. с stdafx теперь проблем вроде как нету, но теперь появились другие ошибки:

1: "c:\api\api\api.cpp(30) : warning C4244: 'return' : conversion from 'WPARAM' to 'int', possible loss of data"  - на строке return "Msg.wParam;" в функции WinMain.

2: "c:\api\api\api.cpp(46) : error C2440: '=' : cannot convert from 'char [7]' to 'LPCWSTR'"  - на строке "WndClass.lpszClassName    =    szAppName;" в функции Register.

3: "c:\api\api\api.cpp(57) : error C2664: 'CreateWindowExW' : cannot convert parameter 2 from 'char [7]' to 'LPCWSTR'"  - на строке "HWND hwnd = CreateWindow(szAppName, szAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);" в функции Create.

Подскажите пожалуйста, что опять не так?

Автор: maxim1000 12.10.2006, 15:19
2 и 3 связаны с одним изменением в VC++2005
раньше по умолчанию define UNICODE не добавлялся, так что программа получалась ANSI, ну и функции, соответственно, с окончанием A
в VC++2005 UNICODE по умолчанию включён, так что надо сделать одно из двух:
1. передавать всем API-функциям unicode'овские строки (L"qqq") (ну или использовать TEXT("qqq"), чтобы универсально было)
2. залезть в свойства проекта и Use Unicode set

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

Автор: ressac 2.6.2007, 22:19
я компилю первые два примера под gcc и у меня вместе с окном открывается консоль, как этого избежать?

Автор: W4FhLF 3.6.2007, 06:42
ressac, ну так создавай проект не консольный или что-нибудь вроде
#pragma comment(linker, "/SUBSYSTEM:WINDOWS")
напиши 

Автор: ressac 3.6.2007, 10:29
W4FhLF, да там проект особо не создашь smile это коносольный компиль, а это

Цитата

#pragma comment(linker, "/SUBSYSTEM:WINDOWS")


не помогло

Автор: W4FhLF 3.6.2007, 10:57
Цитата(ressac @  3.6.2007,  10:29 Найти цитируемый пост)
W4FhLF, да там проект особо не создашь  это коносольный компиль, а это


Что значит консольный компиль? Это зависит от поля Subsystem в заголовке PE файла.

g++ -Xlinker --subsystem -Xlinker windows main.cpp -o main.exe

Всё работает. 

Автор: nerezus 5.6.2007, 12:00
Цитата

Многие, начинающие изучать API (application programming interface – интерфейс программирования приложений), удивляются объему кода, сложности и тп, говорят, что проще сделать в Borlan® Builder®. Если Вы так думаете, то зачем читаете этот текст?
 А разве не легче? ))

Автор: 101 7.6.2007, 11:32
 smile 

Автор: Dronchik 18.6.2007, 10:31
Цитата

Возникает такое сообщение "c:\apiwindow\apiwindow.cpp(83) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
 И exe-файл не создается... Что делать? Нужен ли этот stdafx и как с ним обходиться? 

А ты выбирай emptu proect а потом создовай файл С++ и пиши там что хочеш

Автор: DominiK 8.7.2007, 22:49
Цитата(ShadowPhoenix @ 15.6.2006,  17:55)
По поводу первой програмки... попробовал откомпилировать в MVS2005  и получил такую козу:
Код

------ Build started: Project: simple, Configuration: Debug Win32 ------
Compiling...
code.cpp
z:\prog\vc\first mfc program\simple\simple\code.cpp(5) : error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char [29]' to 'LPCWSTR'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Build log was saved at "file://\\fdoserv\общий доступ\Prog\VC\First MFC program\simple\simple\Debug\BuildLog.htm"
simple - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

 что я тут не понял:
 1. С какого перепугу "MessageBoxW" вместо "MessageBox", в MSDN такой фишки вообще нет... ну это ладно.
 2. поповоду самого "MessageBox"
в MSDN :
Код

Syntax

int MessageBox
(         
           HWND hWnd,
           LPCTSTR lpText,
           LPCTSTR lpCaption,
           UINT uType
);


Parameters

-hWnd
  [in] Handle to the owner window of the message box to be created. If this parameter is NULL, the       message box has no owner window. 
-lpText
  [in] Pointer to a null-terminated string that contains the message to be displayed. 
-lpCaption
  [in] Pointer to a null-terminated string that contains the dialog box title. If this parameter is NULL, the -default title Error is used. 
-uType
  [in] Specifies the contents and behavior of the dialog box. This parameter can be a combination of flags from the following groups of flags.


т.е. по логике вещей должно приводиться??? или я чего не так понимаю.
далее начал химичить пытаясь его запустить хоть как-то... и пришел к такому вот обрезаному виду:
Код
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
    LPCWSTR s1,s2;
    MessageBox(NULL, NULL, NULL, MB_OK|MB_ICONEXCLAMATION);
    return 0;
}


 :qstn так собственно сам вопрос как строку  к этому страшному LPСWSTR приводить... перепробовал все известные мне способы :stena , из знакомых никто не знает :(




MessageBox(NULL, L"Сказала собака баскервилей.",L "Ну, здравствуй, Герасим.", MB_OK|MB_ICONEXCLAMATION);

Автор: LinuxanT 15.2.2008, 07:14
такую тему закрепить наверху имхо надо... smile 

посоветуйте учебник по WinAPI пожалуйста...   smile 

-------------------------
все нашел... ссылки на них есть в http://forum.vingrad.ru/forum/topic-86452.html... 
PS и почему функции удаления своего сообшения тут нед(((

Автор: pycha 31.7.2008, 14:05
драсте у меня была аналогичная трабла, не хотело компилировать я почитал эту тему раскинул мозгами изменил код и скомпилировало нормально(код из книги " win32 API Эфективная разработка приложений" . Вот что у меня получилось
Код

#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
LRESULT CALLBACK WndProc(HWND, UINT,WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstancel,
                   LPSTR lpCmdLine, int nCmdShow)
{
    HWND hMainWnd;
    wchar_t szClassName[] = L"my Class";
    MSG msg;
        WNDCLASSEX wc;

        wc.cbSize        = sizeof (wc);
        wc.style        = CS_HREDRAW| CS_VREDRAW;
        wc.lpfnWndProc    = WndProc;
        wc.cbClsExtra    = 0;
        wc.cbWndExtra    = 0;
        wc.hInstance    = hInstance;
        wc.hIcon        = LoadIcon(    NULL, IDI_APPLICATION);
        wc.hCursor        = LoadCursor(NULL, IDC_ARROW);
        wc.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
        wc.lpszMenuName    = NULL;
        wc.lpszClassName=  szClassName;
        wc.hIconSm        = LoadIcon(NULL, IDI_APPLICATION);
        if(!RegisterClassEx(&wc)){
            MessageBox(NULL, L"не могу зарегестрировать клас", 
                L"ошибка", MB_OK);
            return 0;
        }

        hMainWnd = CreateWindow(szClassName, L"програма с приветом", WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
            (HWND)NULL, (HMENU)NULL,
            (HINSTANCE)hInstance, NULL);
        if(hMainWnd){
            MessageBox(NULL, L"не создается главное окно", L"ошибка", MB_OK);
            return 0;
        }

        ShowWindow(hMainWnd, nCmdShow);
        UpdateWindow(hMainWnd);

        while (GetMessage(&msg,NULL, 0,0)){
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        }
        return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
    HDC hDC;
    PAINTSTRUCT ps;
    RECT rect;

    switch (uMsg)
    {
    case WM_PAINT:
        hDC = BeginPaint (hWnd, &ps);
        GetClientRect(hWnd, & rect);
        DrawText(hDC, L" Hello, world!", -1, & rect,
            DT_SINGLELINE | DT_CENTER |DT_VCENTER);
        
        EndPaint(hWnd,&ps);
        break;

    case WM_CLOSE:
        DestroyWindow(hWnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, uMsg, wParam,lParam);
    }
    return 0;
}

 
но почемуто при запуске выкидывает месаж что несоздается главное окно. Подскажите что тут не так.

Автор: mekhanikus 31.7.2008, 14:34
Цитата(pycha @ 31.7.2008,  14:05)
        if(hMainWnd){
            MessageBox(NULL, L"не создается главное окно", L"ошибка", MB_OK);
            return 0;}

Попробуй так:

Код

if(!hMainWnd){
            MessageBox(NULL, L"не создается главное окно", L"ошибка", MB_OK);
            return 0;}


Если окно создалось успешно, то hMianWnd != 0.

Автор: pycha 31.7.2008, 15:17
да оно! Самое стыдное  што несколько раз сверял с книгой и не заметил.

Автор: pycha 5.8.2008, 00:03
Еще одно. Теперь попал на такую заковырку.
Вобщем вот ошибки.

g:\documents and settings\pycha.pycha-1366613\мои документы\visual studio 2008\projects\project2\textviver\textviver\kdocument.cpp(14) : error C2664: 'std::basic_istream<_Elem,_Traits> &std::basic_istream<_Elem,_Traits>::get(_Elem *,std::streamsize)' : cannot convert parameter 1 from 'wchar_t [200]' to 'char *'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>
        ]
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
g:\documents and settings\pycha.pycha-1366613\мои документы\visual studio 2008\projects\project2\textviver\textviver\kdocument.cpp(16) : error C2440: '<function-style-cast>' : cannot convert from 'wchar_t [200]' to 'std::string'
        No constructor could take the source type, or constructor overload resolution was ambiguous

g:\documents and settings\pycha.pycha-1366613\мои документы\visual studio 2008\projects\project2\textviver\textviver\kdocument.cpp(110) : error C2664: 'TextOutW' : cannot convert parameter 4 from 'const char *' to 'LPCWSTR'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
g:\documents and settings\pycha.pycha-1366613\мои документы\visual studio 2008\projects\project2\textviver\textviver\kdocument.cpp(112) : error C2664: 'TabbedTextOutW' : cannot convert parameter 4 from 'const char *' to 'LPCWSTR'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast


как нужно правильно передавать unicode wchar_t символы апи функциям вместо обычного char

Автор: Dem_max 5.8.2008, 04:42
Цитата

как нужно правильно передавать unicode wchar_t символы апи функциям вместо обычного char

Так и передавай в 
1. TextOutW(...., _T("Привет"),...);
2. TextOut(...., _T("Привет"),...);
3. TextOutW(...., L"Привет",...);
4. TextOut(...., L"Привет",...);

Цитата

cannot convert from 'wchar_t [200]' to 'std::string'

стринг строка должна быть как char, поэтому компилятор и ругается что не может преобразовать wchar_t в char, задавай явно в char

Автор: pycha 5.8.2008, 22:52
cannot convert from 'wchar_t [200]' to 'std::string'

-нащет этого понятно,  но как быть с TextOut если 4 параметр у него lines[i].c_str() это (как я понял это в стандартной библиотеке) не изменять же ее.
TextOut(hdc,x,y,lines[i].c_str(), lines[i].size());

Автор: pycha 7.8.2008, 11:03
поднимаю тему. Что так никто и не подскажет?

Автор: mekhanikus 7.8.2008, 12:34
Цитата(pycha @ 5.8.2008,  22:52)
TextOut(hdc,x,y,lines[i].c_str(), lines[i].size());

Вообщето, TextOut определяется так:

BOOL TextOut(

    HDC hdc,    // handle of device context 
    int nXStart,    // x-coordinate of starting position  
    int nYStart,    // y-coordinate of starting position  
    LPCTSTR lpString,    // address of string 
    int cbString    // number of characters in string 
   );

Поэтому создавай строку 
Код
char szHello = "Hello, World!"


и передавай ее в TextOut.
И будет тебе счастье.

Автор: nerezus 9.8.2008, 11:27
pycha, в настройках проекта отключи UNICODE.

Автор: pycha 11.8.2008, 12:40
Я сделал явный вызов - TextOutA так и решил проблему.
Подскажите где в visual studio 2008 найти графический редактор. Вродебы переикал  все , чтото не верится что его там нет.

Автор: Partizan 11.8.2008, 12:46
pycha, на самом деле полноценного графического редактора там нет)....да и не нужен он...если только несколько пикселей поменять в иконке...

Добавлено через 36 секунд
Цитата

Я сделал явный вызов - TextOutA


имхо такие вызовы - это моветон.

Автор: pycha 11.8.2008, 14:26
А какую прогу можно использовать для этого назначения? paint черезчур неудобный. и не сохраняет файлы в разшерении ico
Я сохранил рисунок в bmp и переименовал в ico . Хотя винда воспренимает корректно, но при компиляции выдало ошибку.

Цитата

 error RC2175 : resource file small.ico is not in 3.00 format

Что же тут делать?

Цитата(Partizan @  11.8.2008,  12:46 Найти цитируемый пост)
имхо такие вызовы - это моветон.

Иначе надо либо отключать юникоде, что я нехочу , или делать функцию которая конвектирует с ansi в unicode.

Добавлено @ 14:26
это во всяком случае мне извесные варианты

Автор: pycha 13.8.2008, 21:50
то каким фоторедактором пользоватся?

Автор: Dem_max 14.8.2008, 05:52
Для работы с иконками я юзаю мощную и удобную прогу ArtIcons Pro 4.21, она разработана нашими. Советую.

Автор: nerezus 15.8.2008, 06:26
Цитата

Подскажите где в visual studio 2008 найти графический редактор.
 Наверное потому, что это среда программирования. Если нужен графический редактор - то советую поставить Photoshop/etc...

Автор: pycha 15.8.2008, 07:57
В старом visual studio 6 он был. В книге описано его использование.
Цитата(Dem_max @  14.8.2008,  05:52 Найти цитируемый пост)
Для работы с иконками я юзаю мощную и удобную прогу ArtIcons Pro 4.21, она разработана нашими. Советую.

Сейчас ее поищу.

Автор: nvrskozzy 16.8.2008, 22:05
Блин. чё-то всё сложно. не подробно расписано :( 
А можно где-нибудь почитать поподробнее и с самых азов этого winapi?
Нифига не ясно =\

Автор: mekhanikus 18.8.2008, 12:38
Ищи К. Г. Финогенова "WIN32 основы ПРОГРАММИРОВАНИЯ",
все разжевано, осталось проглотить.

Автор: Иван4444 18.8.2008, 14:26
такой трабл: к примеру ест ьчисло int j =5;
 хочется его вывести в MessageBox'е , использую всюду unicod, как это селать?.. не один макрос не подходит.

Автор: Иван4444 18.8.2008, 15:04
есе такая задачка : если есть текст, скажем "барабас" то чтобы его вывести достаточно добавить L , а если скажем это переменная (текстовая) , то там надо извращаться.. то добавлять LPWSTR то есче что.... может скажете логику такого решения?... почему именно так?.. и может ест ьу кого небольшая шпаргалка чтобы быстро конвертировать эти значения.

Автор: Dem_max 18.8.2008, 19:53
#include <tchar.h>
int j=5;
TCHAR txt[50];
wsprintf(txt, _T("%d"), j);
MessageBox(NULL, txt, _T("Число"), MB_OK);
MessageBox(NULL,  _T("Это было число"), _T("Число"), MB_OK);

пользуйся макросом _T()
это избавит тебя с переходами с юникода на char  и наоборот, а L это задание чисто юникодовской строки.







Автор: Иван4444 20.8.2008, 14:55
пасиб )

Автор: Sanek123 1.5.2009, 06:44
Хорошо, положим, получилось окно приложения:
Код

#include <windows.h>

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "WindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)

{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default color as the background of the window */
    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Windows App",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nFunsterStil);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */
    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}

Кто-нибудь подскажет, как теперь на форме рисовать кнопку, поле ввода и т.д. Если можно с примером... smile 

Автор: GoldFinch 1.5.2009, 11:24
CreateWindow(_T("BUTTON"),....,hwnd,....);
CreateWindow(_T("EDIT"),....,hwnd,....);

Автор: thefree 4.5.2009, 09:54
Возникает вопрос, отрисовал я кнопочки и поля по средствам CreateWindow в WM_CREAT, в общей суми у меня их получилось 7 штук, после нажатия на кнопку мне надо вывести совсем другое окно. Вопрос заключается в том что мне теперь удалять 7 элементов через destroywindow и отрисовывать новое окно занова? или есть другой более красивый подход.

И еще маленький вопрос, у меня есть функция которая выполняется 30 секунд, по оканчанию её выполнения результат я вывожу через CreateWindow как текст, до этого я хочу чтобы на мести выводимого результата рисовалось "Ожидаем", но оно не отрисовывается ... пока не выполнятся функция, да и многие компоненты указаны до запуска функции не отрисовываются.

Автор: Forsaken 5.7.2009, 20:35
Здравствуйте.
Создал проект на VS2008 откомилировал под WinXP SP3 -все нормально, только вот когда принес EXE на другой компьютер оказалось что он не работает ("не могу запустить из-за неправильной параллельной конфигурации, см. подробности в журнале") в debug/release. Настройки компилятора не трогал (манифест тоже не трогал). Подскажите, пожалуйста, какие настройки нужно устанавливать для того чтобы мой проект заработал на висте?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)