Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2005.07.18;
Скачать: [xml.tar.bz2];

Вниз

Формы, контролы и т.д. на Winapi   Найти похожие ветки 

 
ДГ   (2005-05-24 20:16) [0]

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


 
Kerk ©   (2005-05-24 20:38) [1]

Удалено модератором


 
Kerk ©   (2005-05-24 20:39) [2]

Kerk ©   (24.05.05 20:38) [1]

хм... глюк однако


 
ДГ   (2005-05-24 20:49) [3]

Сорри. Перепутал эху.


 
Sergey Masloff   (2005-05-24 21:01) [4]

Win32 Programmers Reference том 1. ТАкже все есть в MSDN


 
Sergey Masloff   (2005-05-24 21:05) [5]

Блин не посмотрел что на русском тебе надо ;-)


 
Sergey Masloff   (2005-05-24 23:39) [6]

Ну вот тебе пример простейшего MDI приложения. Наслаждайся а потом решай ;-)

program TestMDI;
{*
*  Трансляция Win32 Prog Ref by SM
*}

uses
 Windows, Messages,SysUtils;

type
 THREADLIST = record
  hThread :THandle ;
  lpvNext :Pointer;
 end;
 PTHREADLIST = ^THREADLIST;

{ Глобальные переменные }
var
 hModule : THandle;           { handle исполняемого файла данного процесса      }
 hwndMain : THandle;          { handle главного окна                            }
 fKillAll : Boolean;          { устанавливается в TRUE для остановки всех нитей }
 pHead : PTHREADLIST;         { связаный список записей с информацией о нитях   }

 msg : TMSG;

const MM_NEWWIN = 8001;

procedure ErrorExit(lpszMessage : PChar);
begin
MessageBox(hwndMain, lpszMessage, "Error", MB_OK);
ExitProcess(0);
end;

procedure AddThreadToList(hThread : THandle);
var
 pNode : PTHREADLIST;
begin
pNode := PTHREADLIST(LocalAlloc(LPTR,sizeof(PTHREADLIST)));
if (pNode = nil) then
 ErrorExit("malloc failed");
pNode.hThread := hThread;
pNode.lpvNext := Pointer(pHead);
pHead := pNode;
end;

{
* Каждое дочернее окно имеет собственную нить которая может быть испольована
* для решения связаных с окном заданий - например, для перерисовки окна
}
function ThreadFunc(hwnd : THandle) :DWORD; stdcall;
var
 lKillMe : DWORD;
begin
while (True) do
 begin
 lKillMe := GetWindowLong(hwnd, GWL_USERDATA);
   if ((fKillAll) or (lKillMe = 1)) then
         break;
 {  Делаем что-то полезное }
end;
{ Очистка перед завершением нити }
Result := 0;
end;

{  Обработка сообщений дочернего окна }

function ChildWndProc(hwnd : THandle; uiMessage : DWORD; wParam, lParam : DWORD) : DWORD; stdcall;
var
 lPrevLong : Longint;
begin
case uiMessage of
WM_CLOSE:
   begin
    lPrevLong := SetWindowLong(hwnd, GWL_USERDATA, 1);
    Result := DefMDIChildProc(hwnd, uiMessage, wParam, lParam);
   end;
WM_DESTROY:
   Result := 0;
else
   Result := DefMDIChildProc(hwnd, uiMessage, wParam, lParam);
 end;
end;


 
Sergey Masloff   (2005-05-24 23:39) [7]

продолжение:

function MainWndProc(hwnd : THandle; uiMessage : DWORD; wParam, lParam : DWORD) : DWORD; stdcall;
const
hwndClient :THandle = 0;
dwCount :DWORD = 1;
var
ccsClientCreate :CLIENTCREATESTRUCT;
hwndChildWnd :THandle;
IDThread :DWORD;
pNode :PTHREADLIST;

 dwRes : DWORD ;

 hThrd : THandle;
 mdicCreate : MDICREATESTRUCT;
 tchTitleBarText : PChar;
 lPrev : Longint;
begin
 GetMem(tchTitleBarText,32);
 case uiMessage of
 WM_CREATE:
   begin
  ccsClientCreate.hWindowMenu := 0;
  ccsClientCreate.idFirstChild := 1;
  hwndClient := CreateWindow("MDICLIENT", nil,
   WS_CHILD or WS_CLIPCHILDREN or WS_VISIBLE, 0, 0, 0, 0,
   hwnd, 0, hModule, @ccsClientCreate);
  Result := 0;
   end;
 WM_CLOSE:
   begin
  fKillAll := TRUE;
  pNode := pHead;
  while (pNode <> nil) do begin
   SetThreadPriority(pNode.hThread, THREAD_PRIORITY_HIGHEST);
   dwRes := WaitForSingleObject(pNode.hThread, INFINITE);
   pNode := PTHREADLIST(pNode).lpvNext;
  end;
  Result := DefFrameProc(hwnd, hwndClient, uiMessage, wParam, lParam);
    end;
 WM_DESTROY:
   begin
  PostQuitMessage(0);
  Result := 0;
   end;
  WM_COMMAND:
    begin
      case LoWord(wParam) of
        MM_NEWWIN :
          begin
            tchTitleBarText := PChar(Format("ThreadWindow %d", [dwCount]));
       mdicCreate.szClass := "ThreadWindowClass";
        mdicCreate.szTitle := PChar(tchTitleBarText);
        mdicCreate.hOwner := hModule;
       mdicCreate.x := CW_USEDEFAULT;
            mdicCreate.y := CW_USEDEFAULT;
            mdicCreate.cx := CW_USEDEFAULT;
            mdicCreate.cy := CW_USEDEFAULT;
        mdicCreate.style := 0;
            mdicCreate.lParam := 0;

        { Сообщение клиентскому окну о создании дочернего окна }

        hwndChildWnd := SendMessage(hwndClient,
                WM_MDICREATE,
                0,
                Integer(@mdicCreate));

        if (hwndChildWnd = 0) then
         ErrorExit("Failed in Create Child Window");

        {  Структура используемая для сообщения нити о необходимости завершения }
        lPrev := SetWindowLong(hwndChildWnd, GWL_USERDATA, -1);

         {  Создаем приостановленую! нить чтобы задать ей приоритет и запустить }

        hThrd := CreateThread(nil, { Атрибуты безопасности по умолчанию }
          0, { Размер стека по умолчанию }
          @ThreadFunc,
          Pointer(hwndChildWnd), {  Параметр для функции нити }
           CREATE_SUSPENDED, { Флаг - создаем приостановленой }
          DWORD(IDThread)); { возвращает ID нити }

        if (hThrd = 0) then
         ErrorExit("CreateThread failed");

        AddThreadToList(hThrd);
        Inc(dwCount);

        {
         *  Устанавливаем приоритет меньший чем у первичной нити, чтобы процесс
         *  мог обрабатывать ввод пользователя.
         }

        if not(SetThreadPriority(hThrd, THREAD_PRIORITY_BELOW_NORMAL)) then
         ErrorExit("SetThreadPriorityFailed!");
        if (ResumeThread(hThrd) = -1) then
         ErrorExit("ResumeThread failed!");
        Result := 0;
          end;
      else
        Result := DefFrameProc(hwnd, hwndClient, uiMessage, wParam, lParam);
      end;
    end;
  else
    Result := DefFrameProc(hwnd, hwndClient, uiMessage, wParam, lParam);
  end;
end;

function InitializeApp() : Boolean;
var
 hmenuMain, hmenuPopup : THandle;
wc : WNDCLASS;
begin
 { Класс главного окна }
wc.style := CS_OWNDC;
wc.lpfnWndProc := @MainWndProc;
wc.cbClsExtra := 0;
wc.cbWndExtra := 0;
wc.hInstance := THandle(hModule);
wc.hIcon := LoadIcon(0, IDI_APPLICATION);
wc.hCursor := LoadCursor(0, IDC_ARROW);
wc.hbrBackground := color_btnface + 1;
wc.lpszMenuName := nil;
wc.lpszClassName := "MainWindowClass";
 wc.hInstance := hModule;

 if (RegisterClass(wc) = 0) then
 begin
 result := FALSE;
   Exit;
 end;

 { Оконные классы "дочек" }

wc.lpfnWndProc := @ChildWndProc;
wc.lpszClassName := "ThreadWindowClass";
if (RegisterClass(wc) = 0) then
 begin
 result := FALSE;
   Exit;
 end;

 { Меню для главного окна }

hmenuMain := CreateMenu();
hmenuPopup := CreateMenu();

if not(AppendMenu(hmenuPopup, MF_STRING, MM_NEWWIN, "&New Window")) then
 begin
 result := FALSE;
   exit;
 end;
if not(AppendMenu(hmenuMain, MF_POPUP, hmenuPopup, "&Threads")) then
begin
 result := FALSE;
   exit;
 end;

 { Создаем главное окно }
hwndMain := CreateWindow("MainWindowClass", "Primary Window",
 WS_OVERLAPPED or WS_CAPTION or WS_BORDER or WS_THICKFRAME or
 WS_MAXIMIZEBOX or WS_MINIMIZEBOX or WS_CLIPCHILDREN or
 WS_VISIBLE or WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT,
 CW_USEDEFAULT, CW_USEDEFAULT, 0, hmenuMain, hModule, nil);
 
if (hwndMain = 0) then
begin
 result := FALSE;
   exit;
 end;

{ Устанавливаем фкус }

SetFocus(hwndMain);
Result := TRUE;
end;

begin
 IsMultiThread := True;
 fKillAll := False;
hModule := GetModuleHandle(nil);
if not(InitializeApp()) then
 ErrorExit("InitializeApp failed");
while(GetMessage(msg, 0, 0, 0)) do
 begin
 TranslateMessage(msg);
 DispatchMessage(msg);
end
end.


 
Anatoly Podgoretsky ©   (2005-05-25 09:06) [8]

АПИ не может работать с формами.


 
Marser ©   (2005-05-25 16:45) [9]

В MSDN есть примеры.
Общая идеология такова - для создания главного окна необходимо сперва зарегистрировать его класс. Затем после хорошо описанных действий создаются дочерние окна элементов управления.
Если класс стандартный, то сощдать такое окно можно простым CreateWindow/CreateWindowEx.
Наиболее распротранены - Button, Combobx, ScrollBox, ListBox, StaticText и другие.
Затем каждому контролу нужно установить собственную оконнную процедуру. Иначе обработка будет происходить по умолчанию.
И т.д...


 
Игорь Шевченко ©   (2005-05-25 17:08) [10]


> Затем каждому контролу нужно установить собственную оконнную
> процедуру.


Это лишнее


 
Marser ©   (2005-05-25 17:10) [11]


> Игорь Шевченко ©   (25.05.05 17:08) [10] [Новое
>сообщение][Ответить]
>
> > Затем каждому контролу нужно установить собственную
>оконнную
>> процедуру.
>
>
> Это лишнее

Я не сказал "необходимо". См. далее по тексту:

> Иначе обработка будет происходить по умолчанию.


 
Игорь Шевченко ©   (2005-05-25 17:48) [12]

Marser ©   (25.05.05 17:10) [11]

Слово "нужно" мне привиделось ? :)


 
alpet ©   (2005-05-25 18:15) [13]

Обрабатывать сообщения от контролов принадлежащих некоторому окну можно через обработку сообщения WM_COMMAND (при этом в lParam будет хэндл контрола), трогать же оконную процедуру у каждого контрола безосновательно.


 
Sergey Masloff   (2005-05-26 10:21) [14]

Вот еще с кнопками пример и статическим текстом (в отличие от дельфийского Label - отдельное окно).

program VerySimple;
(*
*  Окно с кнопкой и статик текстом.
*)
uses Windows, Messages;

var wc: TWndClassA;
   Inst, Handle, Button1, Label1, Label2, Edit1, Edit2: Integer;
   Msg: TMsg;
   hFont: Integer;

{ Оконная процедура. Не забывать stdcall}

function WndProc(hWnd, uMsg, wParam, lParam: Integer): Integer; stdcall;
begin
 case uMsg of
 WM_COMMAND :
   begin
     if (lParam = Button1) then
       MessageBoxA(Handle, "Button Clicked!", "Yes", 0);
     Result := 0;
   end;
 WM_DESTROY :
   PostQuitMessage(0);
 else
   Result := DefWindowProc(hWnd, uMsg, wParam, lParam);
 end;
end;

begin
{ регистрируем свой класс окна }
 Inst := hInstance;
 with wc do
 begin
   style         := CS_CLASSDC or CS_PARENTDC;       // Стиль
   lpfnWndProc   := @WndProc;                        // Адрес оконной функции
   hInstance     := Inst;
   hbrBackground := color_btnface + 1;
   lpszClassname := "TESTWINDOW";                    // Имя нового класса
   hCursor       := LoadCursor(0, IDC_ARROW);        // Стандартный курсор
   hIcon         := LoadIcon(Inst, IDI_APPLICATION); // Стандартная иконка
 end;
 RegisterClass(wc);

{ Создаем главное окно программы }
 Handle := CreateWindowEx(WS_EX_WINDOWEDGE, "TESTWINDOW", "Тест",
                          WS_VISIBLE or WS_CAPTION or WS_SYSMENU,
                          200, 200, 200, 85, 0, 0, Inst, nil);

{ На этом окне делаем все прочие элементы - в данном случае LABEL и кнопку}

 Label1 := Createwindow("Static", "", WS_VISIBLE or WS_CHILD or SS_LEFT,
                        8, 12, 80, 13, Handle, 0, Inst, nil);

 Button1 := CreateWindow("Button", "ClickMe", WS_VISIBLE or WS_CHILD or BS_PUSHLIKE or BS_TEXT,
                          100, 10, 75, 39, Handle, 0, Inst, nil);

{ Создаем шрифт для всех элементов. }
 hFont := CreateFont(-11, 0, 0, 0, 400, 0, 0, 0, DEFAULT_CHARSET,
                     OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
                     DEFAULT_PITCH or FF_DONTCARE, "MS Sans Serif");

{ Устанавливаем созданный шрифт для всех элементов }
 if hFont <> 0 then
 begin
   SendMessage(Button1, WM_SETFONT, hFont, 0);
   SendMessage(Label1, WM_SETFONT, hFont, 0);
 end;

{ Прописываем текст на метках (Label) }
 SetWindowText(Label1, "TestLabel");

{ Показать окно, и перерисовать содержимое }
 UpdateWindow(Handle);

{ цикл обработки сообщений, он и будет все время крутиться }
 while(GetMessage(Msg, 0, 0, 0)) do
 begin
   TranslateMessage(msg);
   DispatchMessage(msg);
 end;

end.




Страницы: 1 вся ветка

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

Наверх




Память: 0.52 MB
Время: 0.04 c
14-1119816163
P.N.P.
2005-06-27 00:02
2005.07.18
Запись данных на CD


14-1119646094
palva
2005-06-25 00:48
2005.07.18
Заплати налоги и спи спокойно


3-1118308515
desha
2005-06-09 13:15
2005.07.18
Dll и базы данных.


6-1111061566
FUNKy
2005-03-17 15:12
2005.07.18
ICS и virtual mapping


11-1102852673
kosend
2004-12-12 14:57
2005.07.18
Добавление новой формы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский