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

Вниз

Хм... Вопрос любителям WinAPI :)   Найти похожие ветки 

 
Rouse_ ©   (2007-07-02 21:58) [0]

За все время практической разработки на API столько раз натыкался на несоответствие того, что есть в MSDN реальному положению вещей, что просто иногда перестаешь удивляться и для выяснения некоторых моментов приходится лезть в отладчик, чтобы понять, как именно работает та или иная функция :)
Но сейчас просто теоретический вопрос: кто какие примеры знает неверной отработки апишных функций с заведомо невалидным кодом ошибки, под который в MSDN сказано см. GetLastError, но  GetLastError возвращает ноль :)


 
oxffff ©   (2007-07-02 22:16) [1]

А пример можно?


 
@!!ex ©   (2007-07-02 22:18) [2]

> За все время практической разработки на API столько раз
> натыкался на несоответствие того, что есть в MSDN реальному
> положению вещей, что просто иногда перестаешь удивляться
> и для выяснения некоторых моментов приходится лезть в отладчик,
> чтобы понять, как именно работает та или иная функция :
> )

Никогда с таким не сталкивался... Хотя круг необходимых мне функций API весьма не большой.
Сталкивался с неверным определением функций в зедере дельфи.


 
Yanis ©   (2007-07-02 22:18) [3]

Надеюсь будет озвучено что то сенсационное, раскопанное Розычем в недрах глубокой отладки :)


 
tesseract ©   (2007-07-02 22:19) [4]


>  GetLastError, но  GetLastError возвращает ноль :)


У меня он чаще возвращал левое что-то, а не ноль.


 
TUser ©   (2007-07-02 22:20) [5]

однако, я не единственный чудак, не имевший проблем с соотвествием между msdn и api :)

около двух сотен функций юзал


 
Anatoly Podgoretsky ©   (2007-07-02 22:25) [6]

> @!!ex  (02.07.2007 22:18:02)  [2]

> Сталкивался с неверным определением функций в зедере дельфи.

Сплошь и рядом и в большом количестве, весь windоws.pas сплошное не доразумение, радует что от версии к версии, какие то крохи исправляют.


 
tesseract ©   (2007-07-02 22:34) [7]


> однако, я не единственный чудак, не имевший проблем с соотвествием
> между msdn и api :)


Я в основном с MFC мучался. С API были приколы, но оч редко.


 
Rouse_ ©   (2007-07-02 22:42) [8]


> Надеюсь будет озвучено что то сенсационное, раскопанное
> Розычем в недрах глубокой отладки :)

Пфф... да какое там сенсационное...
Самый простейший пример:

program Project1;

{$APPTYPE CONSOLE}

uses
 Windows;

const
 ClassName = "gravicapa";

var
 WndClassEx: TWndClassEx;

function WindowProc(Wnd: HWND; Msg: Integer;
 WParam: WPARAM; LParam: LPARAM): LRESULT; stdcall;
begin
 Result := 0;
end;

function RegisterWnd: Boolean;
begin
 with WndClassEx do
 begin
   cbSize := SizeOf(TWndClassEx);
   style := CS_HREDRAW or CS_VREDRAW;
   lpfnWndProc := @WindowProc;
   cbClsExtra := 0;
   cbWndExtra := 0;
   hIcon := LoadIcon(0, IDI_APPLICATION);
   hCursor  := LoadCursor(0, IDC_ARROW);
   hbrBackground := COLOR_BTNFACE + 1;
   lpszMenuName := nil;
   lpszClassName := PChar(ClassName);
 end;
 WndClassEx.hInstance := HInstance;
 Result := RegisterClassEx(WndClassEx) <> 0;
end;

var
 A, B: DWORD;
begin
 RegisterWnd;
 if CreateWindow(PChar(ClassName), nil, 0,
     0, 0, 0, 0, 0, 0, HInstance, nil) = 0 then
 begin
   // If the function fails, the return value is NULL.
   // To get extended error information, call GetLastError.
   Writeln("Last error: " + getlasterror);
 end;
 Readln;
end.


 
DVM ©   (2007-07-02 22:45) [9]

Не замечал особых проблем с GetLastError. Но за время интенсивного использования "чиста апи" в течение 2-х с лишним лет натыкался периодически на ошибки как в работе некоторых функций, так и в их описаниях. Последнее что-то с джойстиком было (я тут писал как-то) - явный баг был в системе.


 
Yanis ©   (2007-07-02 22:46) [10]

Ну просто not пропустили :o) Встречался пару раз.


 
DVM ©   (2007-07-02 22:53) [11]


> Ну просто not пропустили :o) Встречался пару раз.

В каком месте пропустили? Здесь что с not что без него фигня получается.

Если CreateWindow() выполнена с ошибкой, то возвращает 0 и надо глядеть GetLastError которая 0 возвращать не должна (но возвращает)


 
Rouse_ ©   (2007-07-02 22:55) [12]


> Yanis ©   (02.07.07 22:46) [10]
> Ну просто not пропустили :o) Встречался пару раз.

Ден, расширь мысль, а то не понял :)


 
Yanis ©   (2007-07-02 23:05) [13]


> Ден, расширь мысль, а то не понял :)

Ой. Не буду, я как обычно тут на пивном облачке летаю :o)


> В каком месте пропустили? Здесь что с not что без него фигня
> получается.

Верно.


 
Rouse_ ©   (2007-07-02 23:06) [14]

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


 
P   (2007-07-03 00:32) [15]


> Rouse_ ©   (02.07.07 23:06) [14]
>
> В действительности данный пример специально был приведен
> (именно в таком виде), чтобы показать, что даже на пустом
> месте может возникнуть данная ситуация. Более интересно
> будет при работе с диалогами, но их мы потом обсудим - пока
> смотрим, кто и что скажет по поводу данного примера :)


Забей. Тестируй на стендовом компе код приложения с заведомо стрессовой нагрузкой и мощным логированием(1), если во время тестов ничего не утекло и не сглючило, то код считается стабильным.

____________________
1 {$IFDEF DEBUG} {$ENDIF} и включить Debug.inc в котором {$DEFINE DEBUG}


 
SlymRO ©   (2007-07-03 05:02) [16]

Остается выяснить насколько правильно, разрешено и предусмотрено оставлять WindowProc с отной строкой
Result := 0;
И потом проверить тот же проект с вызовом DefWndProc...


 
ага   (2007-07-03 07:35) [17]

>см. GetLastError, но  GetLastError возвращает ноль :)

А я чет не понял. У меня этот пример из [8] стабильно 183 возвращает. Дак вольно те nccreate не обрабатывать.


 
Однокамушкин   (2007-07-03 08:47) [18]

Была одна ошибка в MSDN в описании функции GetGlyphOutline, подробностей сейчас не помню, но что-то связано с тем, что MSDN обещал координаты глифа в экранных координатах, а они возвращались во внутреннем представлении шрифта... Ещё одна ошибка описана у Феня Юаня, связана с полигональными регионами... больше, кажется, ни разу не сталкивался...


 
Rouse_ ©   (2007-07-03 09:16) [19]


> Была одна ошибка в MSDN в описании функции GetGlyphOutline

Я именно поэтому в свое время попросил начальство подписаться на MSDN чтобы по приходу новой версии оного сразу смотреть в KB - чего там еще наисправляли :)

Ладно вернемся к нашим баранам :) Ежели в WindowProc код возврата сделать единицу - то пример отработает нормально. Следующая ошибка может быть с любой функцией создания диалога, в состав темплейта  которого входит любой элемент из comctrl32. Если перед этим не вызвать InitCommonControls - то стабильно будет возвращаться INVALID_HANDLE_VALUE но опятьже GetLastError будет упорно молчать :)


 
Игорь Шевченко ©   (2007-07-03 09:42) [20]


> Ежели в WindowProc код возврата сделать единицу - то пример
> отработает нормально


Я конечно понимаю, что настоящие индейцы MSDN не читают - они в них ошибки ищут.

Но Чарльза нашего, Петцольда, хотя бы, почитать все-таки не грех. Он там вскользь упоминает волшебное слово DefWindowProc


 
Rouse_ ©   (2007-07-03 09:49) [21]

Игорь, да это все понятно - но вопрос не в том был, а в отображении ситуации, когда GetLastError молчит :)


 
Игорь Шевченко ©   (2007-07-03 09:53) [22]

Rouse_ ©   (03.07.07 09:49) [21]

А с чего ему не молчать, поясни мне ? Какая, по твоему мнению, должна возвращаться ошибка и почему, а то я что-то не соображу.


 
Однокамушкин   (2007-07-03 09:57) [23]


> Rouse_ ©   (03.07.07 09:16) [19]
> Ладно вернемся к нашим баранам :) Ежели в WindowProc код
> возврата сделать единицу - то пример отработает нормально.
>  Следующая ошибка может быть с любой функцией создания диалога,
>  в состав темплейта  которого входит любой элемент из comctrl32.
>  Если перед этим не вызвать InitCommonControls - то стабильно
> будет возвращаться INVALID_HANDLE_VALUE но опятьже GetLastError
> будет упорно молчать :)

Кстати, недавно в этом форуме столкнулись с аналдогичным поведением всё той же GetGlyphOutline (ветка ещё жива - http://delphimaster.net/view/4-1182240688/): если ей передать буфер меньшего размера, чем требуется, GetGlyphOutline возвращает GDI_ERROR, а GetLastError - 0...


 
Rouse_ ©   (2007-07-03 10:43) [24]


> Какая, по твоему мнению, должна возвращаться ошибка и почему

Что значит какая? Читаем:
1. If the function fails, the return value is NULL. - да функция действительно вернула ноль, это же не отрицается? Читаем далее:
2. To get extended error information, call GetLastError. - а GetLastError возвращает ноль.

Отсюда следует, на основании пункта один, по моему мнению должна возвращятся любая ошибка, код которой отличен от нуля. Я не прав?


 
Игорь Шевченко ©   (2007-07-03 10:48) [25]

Rouse_ ©   (03.07.07 10:43) [24]

Я же говорю, что настоящие индейцы MSDN не читают.

"WM_NCCREATE Notification:

If an application processes this message, it should return TRUE to continue creation of the window. If the application returns FALSE, the CreateWindow or CreateWindowEx function will return a NULL handle. "

(c) оттуда

Never attribute to malice which can be adequately explained by stupidity.


 
Rouse_ ©   (2007-07-03 10:52) [26]

Игорь, не идет об этом речь. GetLastError предназначе для того, чтобы помочь программисту идентифицировать его ошибку в приложении. Какая мне разница что я не обработал WM_NCCREATE? Какая мне разница, что я не вызвал InitCommonControls? Тот же олешный механизм меня почемуто нотифицирует эксепшеном что я не сделал CoInitialize, так почему это не делает этот механизм контроля ошибок?


 
Игорь Шевченко ©   (2007-07-03 10:54) [27]

Rouse_ ©   (03.07.07 10:52) [26]

Вот я и спрашиваю, какая по твоему мнению, должна быть возвращена ошибка ?


 
Rouse_ ©   (2007-07-03 11:02) [28]

Да любая. На InitCommonControls можно тот-же ERROR_MOD_NOT_FOUND. На необработку WM_NCCREATE хотя бы тот-же ERROR_CAN_NOT_COMPLETE.


 
SlymRO ©   (2007-07-03 11:04) [29]

не обработав WM_NCCREATE ты согласился с несозданием окна... и если ты согласился то никакой ошибки в этом нет


 
Rouse_ ©   (2007-07-03 11:06) [30]


> не обработав WM_NCCREATE ты согласился с несозданием окна.

Читай внимательно:

> GetLastError предназначе для того, чтобы помочь программисту
> идентифицировать его ошибку в приложении

Представь что я начинающий, очень сильно начинающий. откуда я могу знать про WM_NCCREATE, если про это явно указано только в описании данного сообщения и не сказано в описании функции CreateWindow?


 
Rouse_ ©   (2007-07-03 11:08) [31]


> SlymRO ©   (03.07.07 11:04) [29]

Да и еще. Подумай зачем мне не соглашаться с созданием окна, если я его явно пытаюсь создать. Да, при этом я допускаю ошибку, причину которой я бы быстро нашел, если мне об этом скажет GetLastError.


 
Игорь Шевченко ©   (2007-07-03 11:08) [32]

Rouse_ ©   (03.07.07 11:02) [28]


> Да любая.


Например, ERROR_INVALID_USER


> На необработку WM_NCCREATE хотя бы тот-же ERROR_CAN_NOT_COMPLETE.


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


 
Игорь Шевченко ©   (2007-07-03 11:10) [33]

Rouse_ ©   (03.07.07 11:08) [31]


> Подумай зачем мне не соглашаться с созданием окна, если
> я его явно пытаюсь создать.


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


 
Rouse_ ©   (2007-07-03 11:11) [34]


> Ты сознательно отказался от создания окна

Блин, я про фому ты про ерему :) Не отказывался я от создания, тем более сознательно. Я начинающий, я не знаю про это. Я знаю только описание функции и механизм котроля ошибок. Этот механизм мне говорит что все в порядке :)


 
Игорь Шевченко ©   (2007-07-03 11:11) [35]

Rouse_ ©   (03.07.07 11:11) [34]


> Я начинающий, я не знаю про это.


А начинающие, Саша, читают матчасть. Чего я и советую.


 
Rouse_ ©   (2007-07-03 11:13) [36]


> Потому что в оконной процедуре по каким-то условиям ты можешь
> решить отказаться от его создания.

Хорошо, там мы упремся окончательно, что тогда скажешь про тот-же

IDD_DIALOG DIALOGEX 0, 0, 143, 76
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP| WS_VISIBLE | WS_CAPTION
EXSTYLE WS_EX_TOPMOST | WS_EX_TOOLWINDOW
CAPTION "Настройки..."
FONT 8, "MS Shell Dlg", 0, 0
BEGIN
  CONTROL "", IDC_HOTKEY, "msctls_hotkey32", 0x50810000, 7, 17, 125, 14
END

без вызова InitCommonControls данный диалог не создасться и ошибки тоже вроде как нет. Тоже читать весь MSDN целиком? :)


 
Игорь Шевченко ©   (2007-07-03 11:24) [37]


> CONTROL "", IDC_HOTKEY, "msctls_hotkey32", 0x50810000, 7,
>  17, 125, 14


замени на "msctls_warmkey32" - тоже не будет ошибки ? (мне проверять лень)


 
Rouse_ ©   (2007-07-03 11:29) [38]

Эээ, попозже... После обеда, если освобожусь, продолжим :)


 
Rouse_ ©   (2007-07-03 13:11) [39]


> замени на "msctls_warmkey32" - тоже не будет ошибки ?

Да проверил. GetLastError = 0


 
Cobalt ©   (2007-07-03 13:24) [40]


> Rouse_ ©   (03.07.07 13:11) [39]
>
>
> > замени на "msctls_warmkey32" - тоже не будет ошибки ?
>
> Да проверил. GetLastError = 0


А должна быть ERROR_CANNOT_FIND_WND_CLASS ?



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

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

Наверх




Память: 0.58 MB
Время: 0.024 c
11-1166629512
DenisY
2006-12-20 18:45
2007.07.29
передать данные в PHP


8-1162468735
toboom
2006-11-02 14:58
2007.07.29
Проблема использования таймера из MMSystem


15-1182920437
pavel_guzhanov
2007-06-27 09:00
2007.07.29
Еще вопрос про php


2-1183511741
Voproshay
2007-07-04 05:15
2007.07.29
Как работать с длительными процессами в программе?


15-1183112964
jack128
2007-06-29 14:29
2007.07.29
Насколько вордовский документ, сохранённый в HTML является XHTML?