Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.12;
Скачать: CL | DM;

Вниз

WinMain   Найти похожие ветки 

 
BackGround   (2006-01-21 21:08) [0]

Решил научится использовать "чистый" WinApi. Перевел код с С++ (сгенерированный Visual C++ 6.0) на Delphi. Все компилируется, но при запуске ничего не происходит. Сам разбраться не смог.

program WindowSample;

uses
 Windows, Messages;

var
 ThisInstance : HINST;
 WindowMain : HWND;

function WindowMainProc(Handle : HWND; Msg : UINT; ParamW : WPARAM; ParamL : LPARAM) : LRESULT; stdcall;
begin
 Result := 0;
 case Msg of
   WM_DESTROY:
     begin
       PostQuitMessage(0);
     end;
   else DefWindowProc(Handle, Msg, ParamW, ParamL);
 end;
end;

function WinMain(Instance, PrevInstance : HINST; lpCmdLine : LPSTR; nCmdShow : Integer) : Integer; stdcall;
var
 Msg : TMSG;
 WndClass : TWNDCLASSEX;
begin
 ThisInstance := Instance;
 Result := 0;

 FillChar(WndClass, SizeOf(TWNDCLASSEX), 0);
 WndClass.cbSize        := SizeOf(TWNDCLASSEX);
 WndClass.style         := CS_HREDRAW or CS_VREDRAW;
 WndClass.lpfnWndProc   := @WindowMainProc;
 WndClass.cbClsExtra    := 0;
 WndClass.cbWndExtra    := 0;
 WndClass.hInstance     := ThisInstance;
 WndClass.hIcon         := 0;
 WndClass.hCursor       := LoadCursor(0, IDC_ARROW);
 WndClass.hbrBackground := COLOR_WINDOW + 1;
 WndClass.lpszMenuName  := nil;
 WndClass.lpszClassName := PAnsiChar("WindowMainClass");
 if RegisterClassEx(WndClass) = 0 then Exit;

 WindowMain := CreateWindow(PAnsiChar("WindowMainClass"),
                            PAnsiChar("Sample Win32Api Applicaion"),
                            WS_OVERLAPPEDWINDOW,
                            10, 10,
                            600, 400,
                            0, 0,
                            ThisInstance,
                            nil);
 if WindowMain = 0 then begin
   UnRegisterClass(PAnsiChar("WindowMainClass"), ThisInstance);
   Exit;
 end;

 ShowWindow(WindowMain, nCmdShow);
 UpdateWindow(WindowMain);

 while GetMessage(Msg, 0, 0, 0) do
 begin
   TranslateMessage(Msg);
   DisPatchMessage(Msg);
 end;

 Result := Msg.wParam;
end;

begin
 WinMain(hInstance, hPrevInst, CmdLine, CmdShow);
end.


 
begin...end ©   (2006-01-21 21:28) [1]

> BackGround   (21.01.06 21:08)

> var
> ThisInstance : HINST;

Это не нужно. Хэндл модуля уже находится в переменной hInstance модуля SysInit, подключающегося автоматически. Значение именно этой переменной следует помещать в поле WndClass.hInstance и передавать в CreateWindow.

> function WinMain(Instance, PrevInstance : HINST; lpCmdLine
> : LPSTR; nCmdShow : Integer) : Integer;

Уберите все параметры.

> else DefWindowProc(Handle, Msg, ParamW, ParamL);

else Result := DefWindowProc(Handle, Msg, ParamW, ParamL);


 
BackGround   (2006-01-21 21:34) [2]


> > function WinMain(Instance, PrevInstance : HINST; lpCmdLine
>
> > : LPSTR; nCmdShow : Integer) : Integer;
>
> Уберите все параметры.


То есть надо писать просто function WinMain: Integer???


 
begin...end ©   (2006-01-21 21:46) [3]

> BackGround   (21.01.06 21:34) [2]

Да.


 
BackGround   (2006-01-21 21:55) [4]

Хендл модуля и DefWindowProc поправил, все ОК.
А вот если убираю параметры из WinMain, то ошибка...


 
begin...end ©   (2006-01-21 22:11) [5]

> BackGround   (21.01.06 21:55) [4]

> А вот если убираю параметры из WinMain, то ошибка...

Какая?


 
begin...end ©   (2006-01-21 22:53) [6]

А, понял :) Наверное, nCmdShow -- undeclared identifier :) Его нужно заменить на CmdShow.

Просто я не понимаю, зачем объявлять функцию с параметрами, и передавать в качестве них глобальные переменные :) Все четыре переменные, которые в C++ передаются как параметры в WinMain, в Delphi являются глобальными и автоматически инициализируются в модулях SysInit и System. Так что hInstance, hPrevInst (этот, правда, особого смысла не несёт), CmdLine и CmdShow можно использовать в любом месте программы.


 
Sergey Masloff   (2006-01-21 23:45) [7]

В дельфи вообще не нужна WinMain. Это чисто сишная вещь для вызова crt библиотекой. В дельфи полным аналогом является помещение кода между

begin
{Вот тут находится то что в це нужно писать в WinMain()}
end.


 
BackGround   (2006-01-22 16:35) [8]

А как изменить цикл

while GetMessage(Msg, 0, 0, 0) do
begin
  TranslateMessage(Msg);
  DisPatchMessage(Msg);
end;


что бы он не грузил процессор на 100%. Пробовал через sleep, но хочу узнать другие альтернативы.


 
GuAV ©   (2006-01-22 17:02) [9]


> А как изменить цикл


Никак его менять не надо.
Дело в том, что для "разгрузки процессора", т.е. передачи управления другим потокам и возврата управления после выполнения определённого условия подходят, кроме Sleep, функции ожидания сообщений  и/или объектов синхронизации, такие как WaitMessage, GetMessage, WaitForSingleObject, MsgWaitForMultipleObjects и другие.
Функция GetMessage передаёт упрвление другим потокам и Ваш поток не получит его, пока не будет получено какое-либо сообщение.
Цикл требовалось бы изменить исли бы для выборки сообщений использовалась бы PeekMessage.



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

Текущий архив: 2006.02.12;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.059 c
15-1137657413
Kerk
2006-01-19 10:56
2006.02.12
Поясните плиз вдовца


4-1130924180
Id
2005-11-02 12:36
2006.02.12
Информация о винте


3-1134722249
Elena_
2005-12-16 11:37
2006.02.12
Как узнать , установлена ли IntrerBase или FireBird на машину


2-1138265784
Geonew
2006-01-26 11:56
2006.02.12
Помогите!!!!!!!!!!!!!


15-1137541401
Германн
2006-01-18 02:43
2006.02.12
Все не любят Оперу или Опера не любит всех?