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

Вниз

Хм... Вопрос любителям 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.58 MB
Время: 0.34 c
3-1177310371
bam
2007-04-23 10:39
2007.07.29
кодировка dbf


2-1183410857
jonimimoni
2007-07-03 01:14
2007.07.29
Hook - перехват клавиатуры


2-1183457683
kilya
2007-07-03 14:14
2007.07.29
ошибка Circular unit reference


4-1171695722
VitAngel
2007-02-17 10:02
2007.07.29
ShellExecute


15-1183450467
Начинающий программист
2007-07-03 12:14
2007.07.29
Книга по Delphi





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский