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

Окно с картинкой на C++


Рекомендуемые сообщения

Помогите пожалуйста. Хочу создать окно для будущего трейнера. В нём мне нужна фоновая картинка, тексты, кнопки. Можно исходный код или видео-урок где-то найти?

Я использую VSC++

Ссылка на комментарий
Поделиться на другие сайты

Поисковик должен быть первым местом куда сначала нужно обратиться, а если не нашел или не понятно, то к нам на форум, но не наоборот. Все то, о чем ты писал там есть.

Ссылка на комментарий
Поделиться на другие сайты

http://msdn.microsof...p/ms536051.aspx

http://msdn.microsof...p/ms536388.aspx

P.S. HDC своего окна ты можешь получить в WM_PAINT сообщении или при помощи GetDC функции.

Ссылка на комментарий
Поделиться на другие сайты

MasterGH. Мде... Смысл тогда от вашего форума?если всё и так уже есть. Вот что за люди? Нет бы помочь, объяснить.

Coder, напомню что я не имел опыта в этом деле.

Неужели нету того кто может помочь? Действительно помочь, а не послать на мсдн в котором я не понимаю ничёрта.

Ссылка на комментарий
Поделиться на другие сайты

/*---------------------------------------------------------------------------*/

Привет!

Для начала, ты не привёл ни строчки кода, в котором сидел и пытался, глядя в

жуткий мсдн, залепить на окошко картинку. У всех сразу же возникло противное

подозрение, будто нужно написать весь код за тебя, а этого никто не любит и

делать не собирается, иначе тема звучала бы как "Помогите сделать окно на C++".

Следовательно, что? Верно. Давай пойдём по порядку и напишем код создания

простого окна.

/*---------------------------------------------------------------------------*/

Ссылка на комментарий
Поделиться на другие сайты

Привет!

Для начала, ты не привёл ни строчки кода, в котором сидел и пытался, глядя в жуткий мсдн, залепить на окошко картинку. У всех сразу же возникло противное подозрение, будто нужно написать весь код за тебя, а этого никто не любит и делать не собирается, иначе тема звучала бы как "Помогите сделать окно на C++". Следовательно, что? Верно. Давай пойдём по порядку и напишем код создания простого окна.

Привет. Дело в том, что я не знаю с чего начать. Я не сильно знаю C++ но мне нравится его синтаксис, поэтому хочу писать на нём. Я имел только опыт редактирования чужих исходников.

А сейчас нашёл все адреса и хотел сделать окошко для трейнера. Но с чего начать писать это окошко?

Ссылка на комментарий
Поделиться на другие сайты

/*---------------------------------------------------------------------------*/

Тэк-с. Давай я немного освобожусь (ремонт дома делаю, мусор убираю) и через

полчасика напишу, с чего начать. Сделаем окошко шаг за шагом, а дальше уже

картинку будем выводить.

/*---------------------------------------------------------------------------*/

Ссылка на комментарий
Поделиться на другие сайты

Тэк-с. Давай я немного освобожусь (ремонт дома делаю, мусор убираю) и через полчасика напишу, с чего начать. Сделаем окошко шаг за шагом, а дальше уже картинку будем выводить.

Хорошо. Спасибо что откликнулся.

Ссылка на комментарий
Поделиться на другие сайты

/*---------------------------------------------------------------------------*/

Итак!

Первое, что нужно сделать - это открыть Visual Studio и создать пустой C++

проект. Дальше в него нужно добавить пустой файл исходника и в нём написать

нечто такое:


#include <windows.h>

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR szCmdLine, int iCmdShow )
{
return 0;
}

Это - точка входа в приложение. Прямо сейчас она у нас возвращает ноль и

программа на этом завершается. Вот картинка, на всякий случай:

89c9295134.png

Идём дальше!

Где-то на просторах 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 - это когда мы закрываем окно. В ответ на это

мы говорим, что пора прощаться, а дальше программа выходит из цикла обработки

сообщений и уже тогда завершается. Картинка:

30e24330da.png

Ну как? Получается что-нибудь? Вопросы есть?

/*---------------------------------------------------------------------------*/

  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

keng, да, получилось такое же окошко. Но есть вопросы.

Жаль что мсдн весь английский :(

Я что-то не пойму, эта функция возвращает функцию?:


LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam )
{
return DefWindowProc( hwnd, message, wparam, lparam );
}

А что делает этот Def? у него такие же аргументы как и у WndProc

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;
}

А обязательно его создавать в RegisterClass?

Ведь мы заполнили структуру окна, указали на неё в RegisterClass, он нам вернёт "всё ок"


if (RegisterClass(&wc))
return 1;

И после него создать окно. Или окно нужно создавать именно в этой функции?

И что будет если RegisterClass вернёт "не ок"? может ли быть такое?

Ещё я не понял про отладку:

Запускаем, проверяем - и ничего не происходит!

тут да, программа завершается.

Отлаживаем код, видим, что hwnd (идентификатор нашего созданного окна) не равняется нулю, значит окно создаётся, видим, что отладчик заходит в функцию самого окна (WndProc), но после этого программа просто завершается.

Как её отладить?

Ссылка на комментарий
Поделиться на другие сайты

/*---------------------------------------------------------------------------*/

1. Функция возвращает не функцию, а её результат. Вызывая DefWindowProc, мы

просим выдать нам результат "по умолчанию", мол, всё хорошо и сообщение было

обработано корректно. И этот результат возвращаем при выходе из WndProc. Иначе

в while(GetMessage()) у нас вернётся что-то не то и цикл прервётся, а

следовательно и программа тоже завершится.

2. WndProc - функция, в которой происходит обработка сообщений окна. Окон может

быть много и каждому нужна такая функция. А ещё можно разным окнам выдавать

одну и ту же оконную процедуру, ага.

3. В RegisterClass мы не создаём окно, а, по сути, описываем его. Какое оно

будет. А создаём окно этого типа (какой зарегистрировали) уже при помощи

CreateWindow, сообщая ему этот самый тип (или класс).

4. Как её отладить - покажу чуть позже, с картинками.

Остальное пока понятно?

PS: Без английского на уровне хотя бы "плохо читаю и со словариком" будет

тяжко, т.к. 99% документации - на английском, а я не бессмертен. Подучи хотя

бы минимально, будет очень круто и полезно, правда.

/*---------------------------------------------------------------------------*/

Ссылка на комментарий
Поделиться на другие сайты

Окон может быть много и каждому нужна такая функция

Как тогда будет выглядеть функция? WinProc2?

А ещё можно разным окнам выдавать одну и ту же оконную процедуру

Если действия для всех окон одинаковые то можно всем указать на один и тот же WinProc? а если нужны иные действия в окне то новый WinProc, да?

создаём окно этого типа (какой зарегистрировали) уже при помощи CreateWindow

Я понимаю что CreateWindow создаёт окно, но что если CreateWindow поместить после RegisterClass а не в нём?

Как её отладить - покажу чуть позже, с картинками.

Было бы не плохо :)

Английский я пока только со словарём. Нет, ну знаю например что CreateWindow это СоздатьОкно. Ну и прочие слова что часто встречаются. Но тексты всякие что на мсдн, не прочитаю сам.

Ну а так пока понятно. Создали точку входа в программу, с неё начинает работать программа. Хотим создать окно, которому нужен класс.

Создаём структуру окна, регистрируем класс указав на структуру окна. Создаём окно, указав в нём уже зарегистрированный класс.

Ссылка на комментарий
Поделиться на другие сайты

/*---------------------------------------------------------------------------*/

1. Да, например, так. Имя сам задаёшь - главное его же указать при регистрации

класса окна. Скажем, класс "окно трейнера". А окон два или три. Значит ты один

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

одна и та же оконная процедура.

2. Да, именно так.

3. CreateWindow мы по факту создаём после вызова RegisterClass, просто при

этом проверяем, что RegisterClass вернула "1" (или "true"), то есть

выполнилась

верно. Примерно так:


if ( RegisterClass) // Если зарегистрировали класс, то
CreateWindow // создаём окно

if ( RegisterClass == 1 )
CreateWindow

if ( RegisterClass == true )
CreateWindow

Второй и третий варианты эквивалентны первому. Это простая проверка, чтобы

убедиться что класс зарегистрировался и всё идёт хорошо, так как если

произойдёт ошибка, то окно создать не получится.

По поводу отладки. Вот картинка:

9501067753.png

Окошко MSVS. Курсор стоит на 30-й строчке, как раз там, где мы окно

регистрируем и проверяем, всё ли прошло верно. Теперь вторая картинка:

0f44c2b3aa.png

Красный кружок слева видишь? Это - breakpoint, или точка останова. Мы помечаем

строчку, на которой хотим приостановить выполнение программы и посмотреть, что

с ней происходит. Устанавливается при помощи F9 или из меню Debug - Toggle

Breakpoint (Отладка - Точка Останова ?). Следующая картинка:

208ae3b100.png

Это мы нажали F5 (или же кнопку с зелёным треугольником сверху, или же меню

Debug - Start Debugging (Отладка - Начать отладку ?) ), программа запустилась

и остановилась на установленном нами брейкпоинте. Последняя картинка:

2e33127fae.png

Это мы немного понажимали F10 и тем самым построчно выполняли программу. Внизу

в окошке, как ты видишь, видны переменные и их значения. Точно так же можно

навести курсор мыши на нужную переменную (например, hwnd) и посмотреть её

значение во время отладки. Продолжить дальше. Итак, ещё раз:

F9 - поставить\снять брейкпоинт на текущей строке.

F10 - пройти на следующую строчку во время выполнения (пошагово).

F5 - запустить отладку.

Shift+F5 - остановить отладку и закрыть программу.

/*---------------------------------------------------------------------------*/

  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

keng, понятно. Но как ты увидел что он заходит в WndProc?

Отлаживаем код, видим, что hwnd (идентификатор нашего созданного окна) не равняется нулю, значит окно создаётся, видим, что отладчик заходит в функцию самого окна (WndProc), но после этого программа просто завершается.

У меня вот что:

78b8e6e6f92afb2650e6021d93ea090b.jpg

Ссылка на комментарий
Поделиться на другие сайты

/*---------------------------------------------------------------------------*/

Судя по твоему скриншоту, у тебя выполнилась функция CreateWindow (успешно,

так как hwnd не равен нулю, что можно увидеть в нижней части окна), а дальше

отладчик встал на строчке return 1. Чтобы посмотреть, попадает ли отладчик в

функцию WndProc, просто поставь брейкпоинт в ней. Можно хоть в самом начале,

после имени функции и аргументов, на строчке с открывающейся фигурной скобкой.

/*---------------------------------------------------------------------------*/

Ссылка на комментарий
Поделиться на другие сайты

keng, она у меня на скриншоте уже закрылась и строчка сразу покраснела.

Ещё вопрос:

указатель на структуру, описывающую меню окна.

То меню что вызывается по клику правой кнопкой мыши? меню верхнего бара или самого окна?

Ссылка на комментарий
Поделиться на другие сайты

  • 3 года спустя...

Если не трудно можешь ответить на вопрос:вот эта программа для фона есть,но как она определяет картинку которую тебе надо(понятно,что картинка должна быть внутри файла,но компилятор все равно  по скриншоту сверху ее не увидит и будет просто стандартный фон)? 

Изменено пользователем Andy
Ссылка на комментарий
Поделиться на другие сайты

2 часа назад, Andy сказал:

Если не трудно можешь ответить на вопрос:вот эта программа для фона есть,но как она определяет картинку которую тебе надо(понятно,что картинка должна быть внутри файла,но компилятор все равно  по скриншоту сверху ее не увидит и будет просто стандартный фон)? 

Картинка находится в ресурсах файла. При старте приложения она оттуда вытаскивается, и устанавливается.

Ссылка на комментарий
Поделиться на другие сайты

1 час назад, Xipho сказал:

Картинка находится в ресурсах файла. При старте приложения она оттуда вытаскивается, и устанавливается.

Ну вот я написал ровно также и ничего не происходит,прога запускается,картинка в формате png есть в файле,а открывается черный фон.Подскажите пожалуйста

Спойлер

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 nCmdShow) 

{ 
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)) 
{ 
SetConsoleTitle (L"Blablabla bla BlAlba"); 
HWND hwnd = CreateWindow("Test Window", "Test" , WS_VISIBLE | WS_CAPTION | WS_SYSMENU , 0, 0, 640, 480, 0, 0, hInstance, 0); 
return 1; 
}; 
return 0; 
}

 

Ссылка на комментарий
Поделиться на другие сайты

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

 

Цитата

wc.hbrBackground =

 

использовать CreatePatternBrush + OleLoadPicture()

 

на GDI+ кажется просто graphics.Drawimage(Bitmap::FromResource(...), 0 ,0)

Ссылка на комментарий
Поделиться на другие сайты

6 минут назад, partoftheworlD сказал:

Нужно здесь

 

 

использовать CreatePatternBrush

Все равно не выходит,пробую 

HBRUSH CreatePatternBrush(_In_ HBITMAP hbmp);

и ровным счетом ничего не происходит.

Ссылка на комментарий
Поделиться на другие сайты

Все та же проблема

5 часов назад, partoftheworlD сказал:

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

 

 

использовать CreatePatternBrush + OleLoadPicture()

 

на GDI+ кажется просто graphics.Drawimage(Bitmap::FromResource(...), 0 ,0)

 

Спойлер

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 nCmdShow) 

{ 
WNDCLASS wc; 
wc.cbClsExtra = 0; 
wc.cbWndExtra = 0; 
 graphics.Drawimage(Bitmap::FromResource(...), 0 ,0);
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)) 
{ 
SetConsoleTitle (L"Blablabla bla BlAlba"); 
HWND hwnd = CreateWindow("Test Window", "Test" , WS_VISIBLE | WS_CAPTION | WS_SYSMENU , 0, 0, 640, 480, 0, 0, hInstance, 0); 
return 1; 
}; 
return 0; 
}

 

 

 

Решил попробовать через  OleLoadPicture,ровно тоже самое

 

Спойлер

#include <olectl.h> 

HRESULT Load(LPCTSTR szFile) 
{ 
CComPtr<IStream> pStream; 

// Load the file to a memory stream 
HRESULT hr = FileToStream(szFile, &pStream); 

if (SUCCEEDED(hr)) 
{ 
// Decode the picture 
hr = ::OleLoadPicture( 
pStream, // [in] Pointer to the stream that contains picture's data 
0, // [in] Number of bytes read from the stream (0 == entire) 
true, // [in] Loose original format if true 
IID_IPicture, // [in] Requested interface 
(void**)&m_pPicture // [out] IPictire object on success 
); 
} 

return hr; 
} 

HRESULT DrawImg(HDC hdc, const RECT& rcBounds) 
{ 
if (m_pPicture) 
{ 
// Get the width and the height of the picture 
long hmWidth = 0, hmHeight = 0; 
m_pPicture->get_Width(&hmWidth); 
m_pPicture->get_Height(&hmHeight); 

// Convert himetric to pixels 
int nWidth = MulDiv(hmWidth, ::GetDeviceCaps(hdc, LOGPIXELSX), HIMETRIC_INCH); 
int nHeight = MulDiv(hmHeight, ::GetDeviceCaps(hdc, LOGPIXELSY), HIMETRIC_INCH); 

// Display the picture using IPicture::Render 
return m_pPicture->Render( 
hdc, // [in] Handle of device context on which to render the image 
rcBounds.left, // [in] Horizontal position of image in hdc 
rcBounds.top, // [in] Vertical position of image in hdc 
rcBounds.right - rcBounds.left, // [in] Horizontal dimension of destination rectangle 
rcBounds.bottom - rcBounds.top, // [in] Vertical dimension of destination rectangle 
0, // [in] Horizontal offset in source picture 
hmHeight, // [in] Vertical offset in source picture 
hmWidth, // [in] Amount to copy horizontally in source picture 
-hmHeight, // [in] Amount to copy vertically in source picture 
&rcBounds // [in, optional] Pointer to position of destination for a metafile hdc 
); 
} 

return E_UNEXPECTED; 
}

 

 

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

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

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