IPB
ЛогинПароль:

> ВНИМАНИЕ!

Прежде чем задать вопрос, смотрите FAQ.
Рекомендуем загрузить DRKB.

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Контролы, API
сообщение
Сообщение #1


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Привет всем. smile.gif

Сейчас начал переводить одно своё приложение на api, весёлое занятие) С механизмами всё понятно, часть проги портировал, а вот с отображением контролов на окне не очень ясно.. Во-первых - всегда ли обязательно создавать, например, label таким образом (для себя в ф-ю обернул):

Procedure createstatic(caption:string;x,y,wid,hei:integer);
begin
CreateWindow('static', pchar(caption), WS_CHILD or WS_VISIBLE,x,y,wid,hei,hwndmain,10000, hInstance, 0);
end;

, или есть какой-то более простой способ внешнего проектирования? Я читал про добавление информации о контролах в ресурсы; это, в принципе, довольно удобно, если сделать быструю компиляцию .rc в .res батником (ну когда нужно быстро что-то изменить там), но вроде как он (способ) нестабильный какой-то.. Во-вторых - где задавать такие параметры static, как шрифт, цвет, размер текста?
Плохо, что вся инфа в msdn по api во-первых, на английском, а во-вторых, там сишный синтаксис. Вот в msdn, например, было написано ShowWindow(hwndMain, nCmdShow);, а делфи второй параметр не принимает такой, а принимает CmdShow (хотя в мсдн вроде и было указано, что от платформы зависит). И ещё, вот, допустим, в процессе исполнения надо мне изменить что-то, например цвет формы. Для этого достаточно вызвать функцию с параметрами, или надо в оконной функции описывать обработку сообщения CTL_COLOR, а потом когда надо отправлять это сообщение?

Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 865
Пол: Мужской
Реальное имя: Вячеслав

Репутация: -  20  +


Цитата
всегда ли обязательно создавать
по-моему - да.
Цитата
где задавать такие параметры static, как шрифт
var
Font: HFONT;
...
Font := CreateFont( -30, 15, 25, 10, 1000, 1, 1, 0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
DEFAULT_PITCH or FF_DONTCARE, 'Courier New' );
...
SendMessage( Btn, WM_SETFONT, Font, 0 );

Примерно так

Добавлено через 2 мин.
Цитата
nCmdShow
Тип то у него int - целый smile.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гость






Цитата
или есть какой-то более простой способ внешнего проектирования?
RC-файл - достаточно простой способ? Тогда используй его. Описание (какие контролы как описываются) есть в MSDN... А на FirstSteps - так и по-русски есть наверняка. В чем нестабильность - не знаю, сколько программ написано - всегда создавали сложные формы в RC-файле, и линковали его к программе (даже не линковали, а просто включали в проект, Дельфи сама сделает, что нужно)...

Цитата
а делфи второй параметр не принимает такой, а принимает CmdShow
А ты не путай формальный параметр с именем переменной, которую ты передаешь в функцию (формальный параметр и в Дельфи тоже называется nCmdChow, а вот переменная, которая содержит значение, указывающее, как было запущено твое окно - называется CmdShow)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Присоединил .rc, вписал там такое:
form
CONTROL "WinAPI. Урок 2. Создание контролов с помощью ресурсов", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 8, 10, 180, 30
CONTROL "Закрыть", 51, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 126, 88, 60, 14



, что-то не кушает.. На firststeps не нашел инфы по ресурсам, нашел только здесь. Убрал описание формы, но пробовал и с ней - результат тот же (и фигурные скобки на begin/end тоже заменять пробовал). И ещё, при создании вручную контрола (окна) мы хоть хэндл можем получить и отправить ему стили например, как Client показал, а при таком способе у нас вроде только текстовый идентефикатор и будет.. Кстати, это наверное удобный способ для переноса с VCL, открываешь блокнотом .dfm и переносишь)

Added: сделал через .res, работает. Яндексом нашёл структуру такого диалога в .rc (можно объявлять несколько шаблонов). Только вот почему-то когда вызываю dialogbox, помимо моего основного окна появляется это новое окно, а мне надо, чтобы то менялось..

Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Гость






Цитата
И ещё, при создании вручную контрола (окна) мы хоть хэндл можем получить и отправить ему стили например, как Client показал, а при таком способе у нас вроде только текстовый идентефикатор и будет..
Ну да, ну да...

А что, вот это сделать тебе какая-то внутренняя преграда запрещает:
// новая функция, которая обрабатывает все команды
// от элементов управления диалога
function DlgProc(hWin: HWND; uMsg: UINT; wp: WPARAM; lp: LPARAM): bool; stdcall;
begin
Result := False;
case uMsg of
// инициализация окна
WM_INITDIALOG:
begin
SendMessage(GetDlgItem(hWin, 51), WM_SETFONT, WPARAM(myFont), 0); // Вот оно, чудо чудное !!!
end;

//обрабатываем команды получаемые от пользователя
WM_COMMAND:
begin
case LoWord(wp) of
// а вот и наша кнопка, с идентификатором 51...
51: EndDialog(hWin, 0);
end;
end;
end;
end;
?

Я сделал диалог, который описал полностью в RC-файле, и запускаю его по нажатию кнопки на своей форме. Вот результат:
Прикрепленное изображение

Сам диалог описан вот так:
TestDialog DIALOG  10, 10, 300, 110
STYLE WS_POPUP | WS_BORDER
CAPTION "Test"
{
CONTROL "WinAPI. Lesson 2", -1, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 8, 10, 180, 30
CONTROL "Close", 51, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 126, 88, 60, 14
}


Никакой перекомпиляции диалога через brcc32.exe на фиг не надо - при внесении изменений в RC-файл Дельфи сама перекомпилирует все, что надо. Для этого нужно самую малость: чтобы RC-файл был корректным, и в правильной кодировке. У меня сложилось впечатление, что если сохранить RC-файл в UTF8, то он компилироваться из Дельфи не будет (надо будет попробовать, а будет ли из ком. строки с использованием brcc32)

Так что ты говоришь нельзя сделать? smile.gif Сообщение послать? Сравни шрифт на Статик-контроле и на кнопке, ага...

Что там у тебя с изменением чего-то не получается? Ты б приаттачил проект полностью (тестовый, который не отрабатывает так, как нужно) - было бы проще посмотреть, в чем проблема...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Цитата
У меня сложилось впечатление, что если сохранить RC-файл в UTF8,


Я сохранял в ANSI, и добавлял в проект через Add.. Ну это уже очень важно, я организовал через батник, пару лишних кликов не критичны smile.gif Я вот не пойму, в контексте api диалог и окно это одно и то же, что ли?

Цитата
Так что ты говоришь нельзя сделать? smile.gif Сообщение послать?


Да, и и правда можно, всё дело в GetDlgItem) А можно шрифт для удобства прямо в .rc вписывать при описании статика?
Цитата

Что там у тебя с изменением чего-то не получается?


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

Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Гость






Цитата
Я вот не пойму, в контексте api диалог и окно это одно и то же, что ли?
Никогда не говори этого своей программе, потому как функция диалога и функция окна - это совершенно разные вещи. По-русски о функции диалога можно почитать здесь

Обратил внимание, что в конце DlgProc отсутствует вызов DefWindowProc? Это не ошибка, в функции диалогового окна вызова этой функции быть не должно:
Цитата
Although the dialog box procedure is similar to a window procedure, it must not call the DefWindowProc function to process unwanted messages. Unwanted messages are processed internally by the dialog box window procedure.


Есть еще несколько отличий функции окна-диалога от функции обычного окна. Если интересно - напишу...

Цитата
А можно шрифт для удобства прямо в .rc вписывать при описании статика?
Можно описать шрифт, который будет установлен для всего диалога, если этого недостаточно - то придется слать сообщение. По отдельности задавать шрифт для каждого контрола в RC нельзя. Это, кстати, совершенно совпадает с поведением CreateWindow... Если ты создаешь контрол, и его шрифт тебя чем-то не устраивает - ты вправе его изменить посылкой сообщения этому контролу. Но прямо при создании (в вызове CreateWindow) ты задать шрифт не можешь.

Для удобства работы с RC-файлами я бы посоветовал тебе скачать какой-нибудь из редакторов (у меня - ResEd 2.0.0.0 для таких нужд). Если надо подправить окошко - очень удобно, он визуальный...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Цитата
Есть еще несколько отличий функции окна-диалога от функции обычного окна. Если интересно - напишу...


Я так понял, диалоги призваны не замещать основные окна, а быть именно диалогами.. Конечно интересно smile.gif
Цитата

Можно описать шрифт, который будет установлен для всего диалога, если этого недостаточно - то придется слать сообщение. По отдельности задавать шрифт для каждого контрола в RC нельзя. Это, кстати, совершенно совпадает с поведением CreateWindow... Если ты создаешь контрол, и его шрифт тебя чем-то не устраивает - ты вправе его изменить посылкой сообщения этому контролу. Но прямо при создании (в вызове CreateWindow) ты задать шрифт не можешь.


На данный момент я буду использовать createwindow. У меня там много тех же Label'ов, и каждый со своими параметрами цвета, размера и шрифта. Поэтому я завёл массив hwnd и создал структуру, где для каждого статика будет храниться соответствующая ему информация, буду создавать в цикле и отправлять информацию о шрифте и т.п. Хотя, с диалогами, конечно, удобнее, когда не надо много атрибутов задавать контролам, возьму на вооружение. Кстати, а можно сделать свой визуальный "класс", ну или как это ещё назвать, типа TPanel ?

Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гость






Цитата
Кстати, а можно сделать свой визуальный "класс", ну или как это ещё назвать, типа TPanel ?
Ну, началось. Ты зачем на WinAPI программу пишешь? Чтобы сляпать самодельную VCL? У тебя не получится, уверяю... Велосипед будет на 24-х колесах, из которых 16 - квадратных, 4 треугольных, а остальные - овальные. Не приедешь ты на таком велосипеде никуда.

Нужны визуальные компоненты - используй VCL. Где-то видел я статью, как писать на WinAPI, используя ООП - извращение еще то, я попробовал, но забросил это дело.

Чуть позже напишу о диалоговых окнах...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Цитата
Где-то видел я статью, как писать на WinAPI, используя ООП - извращение еще то, я попробовал, но забросил это дело.


Аа, что-то типа KOL&MCK, плавали, знаем ) Не такое уж извращение, если сильно не увлекаться этим делом) Что ж, Client, volvo, спасибо за советы smile.gif

Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Ещё одну свою заморочку с api вспомнил. Там есть функция для рисования на устройстве ("в контексте устройства") jpg-картинки? Например, имея хэндл формы, отрисовать там что-то. Пол-инета перерыл, получилось отобразить битмап с помощью loadimage и ещё пары функций, а для jpg нету ничего (loadimage тянет битмапы, курсоры и иконки только).

Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Гость






Либо вот такой бред: [C++,WinAPI]Загрузка картинки , либо берешь тут библиотеку GDI+, и рисуешь через GdipLoadImageFromFile (да в принципе, там много чего есть: MSDN -> GDI+ Reference).

Добро пожаловать в WinAPI smile.gif
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


В бреде я был, только что-то сильно много там всего и непонятного) Библиотеку скачал, посмотрел демки, выбрал вроде как нужное, для открытия gif (ну я так понял, и jpeg тоже должно жевать). Вытащил следующее:

Procedure OnPaint(DC: HDC);
var
graphics : TGPGraphics;
Image: TGPImage;
destinationRect: TGPRectF;
begin
graphics := TGPGraphics.Create(DC);
Image:= TGPImage.Create('vol.gif');
graphics.DrawImage(image, 0, 0);
Image.Free;
graphics.Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
var handle:hdc;
ps:paintstruct;
begin
Handle := BeginPaint(form1.form.Handle, ps);
OnPaint(Handle);
EndPaint(form1.form.handle, ps);
end;


По нажатию кнопки шлю sendmessage(form1.handle,WM_PAINT,0,0);. Что не так?

Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






Итак, результаты экспериментов с отрисовкой JPG без использования доп. библиотек: GDI+ у меня на D2009 не завелся, там что-то поменялось, а качать версию, которая специально предназначена для D2009 мне лень, поэтому возиться с этим не стал.

Способ с OLE. Отработал, но я опять же не стал делать чистое API-приложение, положил на форму TPanel, и отрисовал на ней. Все прекрасно отобразилось:

// В интерфейсной части модуля
function OleLoadPicturePath(szUrlorPath: PWideChar;
unkCaller: IInterface; dwReserved: Integer; drReserved: Cardinal;
const iid: TGUID; ppvRet: Pointer): HRESULT; stdcall;


// а это - в Implementation
uses ActiveX, ComObj;

// Если не описать этого, то получишь ошибку, что OleLoadPicturePath отсутствует в модуле
// olepro32.dll ... Но оно действительно не там, а в oleaut32.dll, и это надо объяснить программе...
function OleLoadPicturePath; external 'oleaut32.dll' name 'OleLoadPicturePath';


const
IID_IPicture: TGUID = '{7BF80980-BF32-101A-8BBB-00AA00300CAB}';

procedure TForm1.Button5Click(Sender: TObject);
var
pic: IPicture;
f_name: WideString;

picWidth, picHeight: Integer;
bounds: TRect; // Здесь оно на фиг не надо. но Render требует...
begin
f_name := 'F:\Test\av-1235.jpg';
Pic := nil;

OleCheck( OleLoadPicturePath(PWideChar(f_name), nil, 0, 0, IID_IPicture, @Pic) );
OleCheck( pic.get_Width(picWidth) );
OleCheck( pic.get_Height(picHeight) );

pic.Render(GetWindowDC(Panel1.Handle), 0, 0, Panel1.Width, Panel1.Height,
0, picHeight, picWidth, -picHeight, bounds);
end;


Не думаю, что будет сложно сделать то же самое на чистом API smile.gif

 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Гость






Кстати, завёлся GDI+ и на 2009-ой Дельфи (достаточно было в Project -> Options -> Delphi Compiler -> Conditional Defines добавить COMPILER5_UP, тогда модули GDIPOBJ/GDIPAPI прекрасно компилируются).

И вот это:
Procedure myOnPaint(DC: HDC);
var
graphics : TGPGraphics;
Image: TGPImage;
destinationRect: TGPRectF;
begin
Image:= TGPImage.Create('F:\Test\av-1235.jpg');
graphics := TGPGraphics.Create(DC);
graphics.DrawImage(image, 0, 0);
Image.Free;
graphics.Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
var ps:paintstruct;
begin
BeginPaint(form1.Handle, ps);
myOnPaint(Form1.Canvas.Handle);
EndPaint(form1.handle, ps);
end;

очень даже рисует JPG-файл на канве формы. Обрати внимание: я не передаю в myOnPaint тот DC, который получен от BeginPaint-а, я передаю хендл канвы формы. Возможно в API-проекте и нужно будет передавать так, как делаешь ты, но мне все еще лень ( smile.gif ) делать все ручками, я проверил на VCL-проекте. Может, попозже вечером, соберусь и сделаю API-проект, и там все проверю... Или ты проверь и выложи результаты.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Сейчас как раз ковырялся с gdi, хорошо, что обновил форум smile.gif Просто не хотелось отдавать 20 кб на откуп activex и comobj (хотя способ, конечно, рабочий). У меня на D2007, кстати, тоже не завелась gdi - видела ошибку в коде, поэтому пишу под семёркой сейчас.

Цитата
Обрати внимание: я не передаю в myOnPaint тот DC, который получен от BeginPaint-а, я передаю хендл канвы формы.


Вот это немного странно, в демо-примере наоборот, я делал всё так же, и не работало. Всё не мог с этим смириться) Почему-то в BeginPaint передаётся хэндл формы, а в MyOnPaint - хэндл канвы формы. Кстати, на VCL название процедуры OnPaint действительно нужно менять smile.gif

Да, в api-проекте нужно делать, как делал я. Прикрепляю демо-пример.


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Там в этой GDI есть тип непонятный какой-то, называется IStream, якобы поток. С T<...>Stream его ассоциировать никак не получается, да даже и описать переменную такого типа тоже нельзя. Он используется во многих функциях загрузки изображений. Поползал по юнитам, нашёл только что он является интерфейсом от некого ISequentialStream (которого, впрочем, моя программа тоже не видит, наверное, это всё приватные структуры). Это я так картинки из ресурсов гружу:

Function LoadJpegRes(const ID: string): TStream;
var
RS: TResourceStream;
begin
RS:=TResourceStream.Create(HInstance, ID, 'JPEG');
result:=TStream.create;
try
RS.Seek(0, soBeginning);
Result.CopyFrom(rs,rs.size);
finally
RS.Free;
end;
end;

Procedure myOnPaint(DC: HDC;x,y:integer;stream:TStream);
var
graphics : TGPGraphics;
Image: TGPImage;
destinationRect: TGPRectF;
begin
Image:= TGPImage.Create();
GdipLoadImageFromStream(stream,image); //<-тут ошибка
graphics := TGPGraphics.Create(DC);
graphics.DrawImage(image, x, y);
Image.Free;
graphics.Free;
end;

Procedure getimage(id:string;x,y:integer); //<--изначально собираюсь вызывать её с ID ресурса и координатами
var ps:TPaintStruct;
begin
BeginPaint(form1.form.Handle, ps);
myOnPaint(Form1.form.Canvas.Handle,x,y,loadjpegres(id));
EndPaint(form1.handle, ps);
end;



Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Гость






Цитата
ам в этой GDI есть тип непонятный какой-то, называется IStream, якобы поток.
Не тип, а интерфейс. IStream Interface

Вот тут посмотри: http://www.delphikingdom.com/asp/answer.asp?IDAnswer=48264
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


mea culpa
*****

Группа: Пользователи
Сообщений: 1 372
Пол: Мужской
Реальное имя: Николай

Репутация: -  24  +


Спасибо за ссылку, сопоставил коды, получилось:

procedure TForm1.Button1Click(Sender: TObject);
var stream:IStream;
image:TGPImage;
graphics:TGPGraphics;
begin
with TResourceStream.Create(hInstance,'PIC1','JPEG') do try
OleCheck(CreateStreamOnHGlobal(0,True,Stream));
OleCheck(Stream.Write(Memory,Size,nil));
Image:=TGPBitmap.Create(Stream);
graphics:=TGPGraphics.Create(form1.Canvas.Handle);
graphics.DrawImage(image, 0, 0, 100,100);
finally
Free;
image.free;
graphics.Free;
end;
end;



Сообщение отредактировано: Unconnected -


--------------------
"Знаешь, стыдно - когда не видно, что услышал всё, что слушал.."
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 20.04.2024 5:25
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name