Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.08;
Скачать: [xml.tar.bz2];




Вниз

Как создавать формы с разными контролами на чистом API? 


Oxy2   (2001-10-23 23:23) [0]

Привет, всем!

Может ли кто нибуть прислать или хотя бы подсказать где можна взять простенькие примеры создания форм, разных контролов на них, создание обработчиков событий этих контролов и т.д. на чистом API (на Delphi или в крайнем случае на C). Вобщем простенькие примеры программирования на API.



Jochua   (2001-10-24 06:25) [1]

Пиши подскажу, что знаю.



Oxy2   (2001-10-25 00:55) [2]

Ну вот например такое. Надо сделать форму на которой будет ListView и две кнопки (Button). Должна быть возможность обрабатывать события от кнопок и от ListView.



Иван Шихалев   (2001-10-25 01:10) [3]

А чем тебя WM_COMMAND и WM_NOTIFY не устраивают?



Alien   (2001-10-25 02:51) [4]

>Oxy2
Про события забудьте. В Win API событий нет. Там есть сообщения, вот их и обрабатывайте.



Jochua   (2001-10-25 08:01) [5]

Вот посмотри, я как то делал пример по такой же просьбе:

program listbox;

uses
windows, messages;

var
wc : TWndClassEx;
Wnd : HWND;
Msg : TMsg;

function WindowProc(wnd : HWND; Msg : Integer; WParam : WParam; LParam : Longint): Longint; stdcall;
const
BUFFER = MAX_PATH;
var
I : Integer;
CurDir : array[0..BUFFER-1] of Char;

Begin
Result := 0;
case msg of

wm_destroy :
Begin
postquitmessage(0);
exit;
Result:=0;
End;

wm_command :
Begin
case loword(wParam) of
200 :
case hiWord(wParam) of
lbn_selchange :
begin
I := SendMessage(lParam, LB_GETCURSEL, 0, 0);
SendMessage(lParam, LB_GETTEXT, I, Integer(@CurDir));
SetWindowText(GetDlgItem(Wnd, 222), CurDir);
end;
lbn_dblclk :
begin
I := SendMessage(lParam, LB_GETCURSEL, 0, 0);
SendMessage(lParam, LB_GETTEXT, I, Integer(@CurDir));
SetWindowText(GetDlgItem(Wnd, 221), CurDir);
end;
end;

100 :
begin
GetCurrentDirectory(SizeOf(CurDir), CurDir);
DlgDirList(Wnd, CurDir, 200, 0, DDL_DIRECTORY);
end;

end;
End;
else
Result := DefWindowProc(wnd, msg, wparam, lparam);
end;
End;

begin
wc.cbSize := sizeof(wc);
wc.style := cs_hredraw or cs_vredraw;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := HInstance;
wc.hIcon := LoadIcon(0, IDI_APPLICATION);
wc.hCursor := LoadCursor(0, idc_arrow);
wc.hbrBackground := COLOR_BTNFACE + 1;
wc.lpszMenuName := nil;
wc.lpszClassName := "listbox example";

RegisterClassEx(wc);

Wnd := CreateWindowEx(0, "listbox example", "ListBoxes Demo",
ws_overlapped or ws_sysmenu,
100, 150, 360, 200,
0, 0,
Hinstance, nil);

CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", NIL, WS_BORDER or LBS_NOTIFY or WS_CHILD or WS_VISIBLE or LBS_MULTICOLUMN or LBS_SORT or LBS_EXTENDEDSEL, 10, 70, 200, 100, Wnd, 200, hInstance, NIL);

CreateWindowEx(0, "STATIC", "dbl_click:", WS_VISIBLE or WS_CHILD, 10, 10, 60, 20, Wnd, 0, hInstance, NIL);
CreateWindowEx(0, "STATIC", NIL, WS_VISIBLE or WS_CHILD, 75, 10, 300, 20, Wnd, 221, hInstance, NIL);

CreateWindowEx(0, "STATIC", "Select:", WS_VISIBLE or WS_CHILD, 10, 40, 60, 20, Wnd, 0, hInstance, NIL);
CreateWindowEx(0, "STATIC", NIL, WS_VISIBLE or WS_CHILD, 75, 40, 300, 20, Wnd, 222, hInstance, NIL);

CreateWindowEx(0, "BUTTON", "Scan Directory", BS_PUSHBUTTON or WS_CHILD or WS_VISIBLE, 220, 130, 120, 25, Wnd, 100, hInstance, NIL);

ShowWindow(Wnd, CmdShow);

While GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.



Jochua   (2001-10-25 08:03) [6]

Вот посмотри, я как то делал пример по такой же просьбе:

program listbox;

uses
windows, messages;

var
wc : TWndClassEx;
Wnd : HWND;
Msg : TMsg;

function WindowProc(wnd : HWND; Msg : Integer; WParam : WParam; LParam : Longint): Longint; stdcall;
const
BUFFER = MAX_PATH;
var
I : Integer;
CurDir : array[0..BUFFER-1] of Char;

Begin
Result := 0;
case msg of

wm_destroy :
Begin
postquitmessage(0);
exit;
Result:=0;
End;

wm_command :
Begin
case loword(wParam) of
200 :
case hiWord(wParam) of
lbn_selchange :
begin
I := SendMessage(lParam, LB_GETCURSEL, 0, 0);
SendMessage(lParam, LB_GETTEXT, I, Integer(@CurDir));
SetWindowText(GetDlgItem(Wnd, 222), CurDir);
end;
lbn_dblclk :
begin
I := SendMessage(lParam, LB_GETCURSEL, 0, 0);
SendMessage(lParam, LB_GETTEXT, I, Integer(@CurDir));
SetWindowText(GetDlgItem(Wnd, 221), CurDir);
end;
end;

100 :
begin
GetCurrentDirectory(SizeOf(CurDir), CurDir);
DlgDirList(Wnd, CurDir, 200, 0, DDL_DIRECTORY);
end;

end;
End;
else
Result := DefWindowProc(wnd, msg, wparam, lparam);
end;
End;

begin
wc.cbSize := sizeof(wc);
wc.style := cs_hredraw or cs_vredraw;
wc.lpfnWndProc := @WindowProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := HInstance;
wc.hIcon := LoadIcon(0, IDI_APPLICATION);
wc.hCursor := LoadCursor(0, idc_arrow);
wc.hbrBackground := COLOR_BTNFACE + 1;
wc.lpszMenuName := nil;
wc.lpszClassName := "listbox example";

RegisterClassEx(wc);

Wnd := CreateWindowEx(0, "listbox example", "ListBoxes Demo",
ws_overlapped or ws_sysmenu,
100, 150, 360, 200,
0, 0,
Hinstance, nil);

CreateWindowEx(WS_EX_CLIENTEDGE, "LISTBOX", NIL, WS_BORDER or LBS_NOTIFY or WS_CHILD or WS_VISIBLE or LBS_MULTICOLUMN or LBS_SORT or LBS_EXTENDEDSEL, 10, 70, 200, 100, Wnd, 200, hInstance, NIL);

CreateWindowEx(0, "STATIC", "dbl_click:", WS_VISIBLE or WS_CHILD, 10, 10, 60, 20, Wnd, 0, hInstance, NIL);
CreateWindowEx(0, "STATIC", NIL, WS_VISIBLE or WS_CHILD, 75, 10, 300, 20, Wnd, 221, hInstance, NIL);

CreateWindowEx(0, "STATIC", "Select:", WS_VISIBLE or WS_CHILD, 10, 40, 60, 20, Wnd, 0, hInstance, NIL);
CreateWindowEx(0, "STATIC", NIL, WS_VISIBLE or WS_CHILD, 75, 40, 300, 20, Wnd, 222, hInstance, NIL);

CreateWindowEx(0, "BUTTON", "Scan Directory", BS_PUSHBUTTON or WS_CHILD or WS_VISIBLE, 220, 130, 120, 25, Wnd, 100, hInstance, NIL);

ShowWindow(Wnd, CmdShow);

While GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end.



Oxy2   (2001-10-25 23:50) [7]

Привет, всем!

2Иван Шихалев
>А чем тебя WM_COMMAND и WM_NOTIFY не устраивают?
Меня они возможно и устраивают, но я об этом пока еще не знаю. :-)))
Ну я же написал, что только учусь прграммированию на чистом API. Раньше я тоже использовал API, но только некоторые отдельные нужные мне функции, а на чистом API я пока еще только учусь. Я пока знаю только как создавать окна и обрабатывать их месаги. В принципе, я пробовал создавать и другие контролы на окне, но для каждого создавал отдельную функцию окна. Это мне не очень понравилось (а если у меня 100 кнопок) и я подумал, что возможно существуют более простые пути. Потому и задал этот вопрос.

2Alien
>Про события забудьте. В Win API событий нет. Там есть сообщения, вот их и >обрабатывайте.
Я знаю что в винде не события, а месаги. Это просто так, по привычке, сорвалось. :-))

2Jochua
ОГРОМНОЕ спасибо за пример. Но у меня снова вопрос. Я хотел бы использовать ListView, а не ListBox. Не подскажете какое у него имя класа.



Jochua   (2001-10-26 06:28) [8]

Открываем файл rw32core.dll (это в BIN у Delphi) и находим - SysListView32. Если создавать объекты через WinAPI, то мимо этой библиотеки не пройти. А там как раз и продекларировано все что Delphi может понять. Потом открываем Messages.pas - это Source/RTL/Win - и смотрим все сообщения на нужный нам объект.



Oxy2   (2001-10-26 23:34) [9]

2Jochua
Я че то совсем ничего не понял. А как тогда VC++ без этой rw32core.dll работает. Вот я пишу вместо создания ListBox-а в вашем прмере такую строчку

CreateWindowEx(WS_EX_CLIENTEDGE, "SysListView32", NIL, WS_CHILD Or
WS_VISIBLE Or WS_VSCROLL Or WS_BORDER Or WS_CLIPSIBLINGS, 10, 70, 200, 100, Wnd, 200, hInstance, NIL);

Но ListView чего то ни в дугу не хочет создаваться. Окно появляется, но ListView на нем нет.



Jochua   (2001-10-29 10:04) [10]

Этот файл нужен только для Delphi, у VC++ все описания находятся в файлах с расширением ".H". Только что проверил (D5, Win98) все работает. Если хочешь можешь писать по мылу, в одном из ответов есть адрес.



nikkie   (2001-10-29 13:35) [11]

>Joshua
чушь какая-то. причем здесь rw32core.dll?
ее product name - Borland Resource Compiler DLL
никаких доп. библиотек от Борланда при написании на апи не требуется.

>Oxy2
перед использованием Common Controls требуется вызов InitCommonControlsEx



Jochua   (2001-10-29 13:53) [12]

>nikkie
Ни какая это не чушь. Посмотри внимательнее, BRCC32 при своей работе вызывает именно эту библиотеку и!!! если не найдет декларированного компонента от WinAPI, то компилировать откажется. InitCommonControlsEx естественно вызывать требуется.



nikkie   (2001-10-29 14:05) [13]

запускаем brcc32 и читаем "Borland Resource Compiler". и причем здесь он?



Иван Шихалев   (2001-10-29 20:22) [14]

> Jochua

Что это за зверь такой - "декларированный компонент от WinAPI"



kowdle   (2001-10-30 00:07) [15]

Иди на ... KOL http://bonanzas.rinet.ru/rindex.htm



Jochua   (2001-10-30 06:18) [16]

Ну если посмотреть внимательно о чем писалось ранее, то был вопрос:
Я хотел бы использовать ListView, а не ListBox. Не подскажете какое у него имя класа.
на что и было отвечено:
Открываем файл rw32core.dll (это в BIN у Delphi) и находим - SysListView32.
Хотелось бы мне знать, как те, что слишком много знают, смогут откомпилировать проект в котором применяется компонент, не описанный в данной библиотеке. Заметьте также, что автор вопроса давно не участвует в этом словоблудии, я также отключаюсь. Отвечу только автору.



nikkie   (2001-10-30 09:40) [17]

>Jochua
ok, отключайся. только несколько слов в догонку.

на вопрос автора "какое имя класса" есть 2 логичных ответа
1. смотрим хелп (MSDN или Win32 SDK) - видим WC_LISTVIEW. там же находим пример.

2. смотрим сорсы VCL, а именно, commctrl.pas и comctrls.pas. видим там декларацию WC_LISTVIEW и кучу любопытного кода, например, безопасный способ использования InitCommonControlsEx.

по поводу твоего ответа. "Открываем файл rw32core.dll" - это в notepad"e, что ли? а если я там вижу BorBtn, BorRadio, ... - это имеет отношение к WinAPI? а если я там еще увижу "VasjaPupkin", то могу ли попробовать создать окно такого класса?

несколько твоих цитат из-за которых я прицепился.

"Если создавать объекты через WinAPI, то мимо этой библиотеки [rw32core.dll] не пройти. А там как раз и продекларировано все что Delphi может понять." [спокойно прохожу. и Oxy2 прошел мимо...]

"Этот файл нужен только для Delphi, у VC++ все описания находятся в файлах с расширением ".H"." [аналогия между rw32core.dll и сишными хедерами, мягко говоря, не понятна]

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



_   (2001-10-30 14:49) [18]

>nikkie
Как жаль, что эти форумы посещают такие хамы. Жаль. И гонора - не унести.



Oxy2   (2001-11-01 00:04) [19]

Привет!

Спасибо всем за советы. Извините что не участвовал. Просто у меня сейчас сессия - забегался и почту пару дней вообще не читал.
И не надо из-за меня ругаться, а то в конце концов я виноватый получусь за то что задал вопрос. А этого мне не очень хочется. :-))

Теперь к делу. Из ваших ответов я наконец понял почему этот ListView не создавался. Надо было перед созданием вызывать функцию InitCommonControlsEx, а я этого не сделал (потому что ничего об этом не знал). Но теперь все хорошо и ListView создается нормально. Правда у меня небольшая заминочка с InitCommonControlsEx вышла. В эту функцию надо передавать какую то структуру. Мне впадло было разбираться и я просто использовал функцию InitCommonControls. С ней нормально все работает, но все же интересно, что делает функция InitCommonControlsEx.
Может кто нибудь доходчиво обяснить?
И что это за безопасный способ использования InitCommonControlsEx?



nikkie   (2001-11-01 09:46) [20]

собственно в MSDN все написано.

void InitCommonControls(VOID);
Registers and initializes the common control window classes. This function is obsolete. New applications should use the InitCommonControlsEx function.

короче, microsoft говорит, что надо использовать InitCommonControlsEx. Тем более, что она более гибкая. Структура состоит всего из 2 полей, так что использовать совсем просто

var
ICC: TInitCommonControlsEx;
begin
ICC.dwSize := SizeOf(TInitCommonControlsEx);
ICC.dwICC :=
ICC_LISTVIEW_CLASSES | ICC_TREEVIEW_CLASSES | ICC_TAB_CLASSES;
// перечисляем те классы, которые собираемся использовать
InitCommonControlsEx(ICC);
end;

есть только одно но. в хелпе на InitCommonControlsEx написано Version 4.70. Вот расшифровка
Version Distribution Platform
4.00 Microsoft® Windows® 95/Windows NT® 4.0.
4.70 Microsoft® Internet Explorer 3.x.
4.71 Microsoft® Internet Explorer 4.0.
4.72 Microsoft® Internet Explorer 4.01 and Windows® 98.
5.00 Microsoft® Internet Explorer 5.
5.00 Microsoft® Windows® 2000 and Windows Me.
5.80 Microsoft® Internet Explorer 5.
5.81 Microsoft® Windows 2000 and Windows Me.
6.00 Microsoft® Windows XP.

то есть при условии, что у юзера стоит Win95 без какого-либо IE этой функции в comctl32.dll не окажется. ситуация трудно вообразимая, но возможная :).

Но дельфи (а точнее, commctrl.pas) нам помогает. InitCommonControlsEx подгружается динамически, а не статически. причем как _InitCommonControlsEx, а InitCommonControlsEx - это просто паскальная функция
Result := Assigned(_InitCommonControlsEx) and _InitCommonControlsEx(ICC);

вариант 1. просто используем InitCommonControlsEx
вариант 2. мы сильно озабочены проблемой запуска своей программы на Win95 без IE и пишем что-то типа
if (not InitCommonControlsEx(ICC)) then InitCommonControls;
вариант 3. мы не морочим себе голову и используем InitCommonControls. хоть она и obsolete, но 100%, что MS ее в следующих версиях не выкинет.




Форум: "WinAPI";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.08;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.79 MB
Время: 0.058 c
1-22129           Aleksandr             2001-12-19 16:04  2002.01.08  
Как убрать мерцание своего скроллбара?


14-22379          Феликс                2001-11-05 19:54  2002.01.08  
Покажи? - А может не надо? -Покажи тебе говорят!


4-22497           Syrius                2001-11-07 09:13  2002.01.08  
Delphi 6 и Win32 API


14-22389          sudiv                 2001-11-08 15:38  2002.01.08  
CashFiesta


3-21900           vano                  2001-12-07 11:13  2002.01.08  
TString и String