информационная безопасность
без паники и всерьез
 подробно о проекте
За кого нас держат?Все любят мед
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Мощные индийские ключи 
 Срочные патчи для критических уязвимостей... 
 Очередной рекордный патч Microsoft 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
резюме всего 17.02.02 22:57  Число просмотров: 1038
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
рассмотрим два понимания ВАЛИДНОСТИ: теоретическую и практическую
теоретически алгоритм ИНВАЛИДЕН в принципе
чтобы не тратить попусту время приведу тестовую прожку,
доказывающую теоретическую ИНВАЛИДНОСТЬ алгоритма
--------------------------------- test.cpp ------------------------------
#include <windows.h>
#include <stdio.h>
#include "test.h"

HINSTANCE Instance;

HWND MainWindow;

HWND TestCreateWindow(void); // форвард
HWND CreateAnotherWindow(void); // форвард

char TestWNDCLASSName [] = "Test WNDCLASS name";
WNDCLASS TestWNDCLASS;
char TestWindowTitle [] = "Test window";

char AnotherWNDCLASSName [] = "Some WNDCLASS name";
WNDCLASS AnotherWNDCLASS;
char AnotherWindowTitle [] = "Some another window";

long WINAPI CALLBACK MainWindowProc
(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
HWND HWNDSavedByCoder;
switch (msg)
{
case WM_COMMAND:
{
switch (wParam)
{
case MWM_FILE_EXIT:
{
PostQuitMessage(0);
return 0;
}
case MWM_ACTION_TEST1_CREATEWINDOW:
{
// 1.Создаем окно
HWNDSavedByCoder = TestCreateWindow();
// 2.Запоминаем его hwnd
if (NULL != HWNDSavedByCoder)
{
// 3.тра ля ля
MessageBox(hWnd, "Please close manually [TEST WINDOW] and press OK to continue", "Your action here", MB_OK);
FILE* file = fopen("test.log", "wb");
fprintf(file,"HWNDSavedByCoder = %x\n", HWNDSavedByCoder);
for (;;)
{
HWND tempHWND = CreateAnotherWindow();
fprintf(file,"tempHWND = %x\n", tempHWND);
if (HWNDSavedByCoder == tempHWND)
{
MessageBox(tempHWND, "This really innocent window will now be destroyed", "look!", MB_OK);
break;
}
fflush(file);
}
// 4.закрываем окно по запомненому hwnd
DestroyWindow(HWNDSavedByCoder);
fclose(file);
Sleep(1000);
for(;;)
{
HWND tempHWND = GetForegroundWindow();
if (tempHWND == MainWindow) break;
DestroyWindow(tempHWND);
}
}
break;
}
case MWM_ACTION_TEST2_CREATEWINDOW:
{
// 1.Создаем окно
HWNDSavedByCoder = TestCreateWindow();
// 2.Запоминаем его hwnd
if (NULL != HWNDSavedByCoder)
{
// 3.тра ля ля
MessageBox(hWnd, "Please close manually [TEST WINDOW] and press OK to continue", "Your action here", MB_OK);
FILE* file = fopen("test.log", "wb");
fprintf(file,"HWNDSavedByCoder = %x\n", HWNDSavedByCoder);
for (;;)
{
HWND tempHWND = CreateAnotherWindow();
fprintf(file,"tempHWND = %x\n", tempHWND);
if (HWNDSavedByCoder == tempHWND)
{
MessageBox(tempHWND, "This really innocent window will now be destroyed", "look!", MB_OK);
break;
}
DestroyWindow(tempHWND);
fflush(file);
}
// 4.закрываем окно по запомненому hwnd
DestroyWindow(HWNDSavedByCoder);
fclose(file);
}
break;
}
case MWM_HELP_ABOUT:
{
MessageBox(hWnd, "www.BugTraq.ru/forum\ntest proggy by [z0]", "About", MB_OK);
break;
}
}
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

long WINAPI CALLBACK DummyWindowProc
(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain
(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
Instance = hInstance;

char SomeWNDCLASSName [] = "Main WNDCLASS name";
WNDCLASS SomeWNDCLASS;

char MainWindowTitle [] = "Main window";

SomeWNDCLASS.style = CS_HREDRAW | CS_VREDRAW;
SomeWNDCLASS.lpfnWndProc = MainWindowProc;
SomeWNDCLASS.cbClsExtra = 0;
SomeWNDCLASS.cbWndExtra = 0;
SomeWNDCLASS.hInstance = Instance;
SomeWNDCLASS.hIcon = NULL;
SomeWNDCLASS.hCursor = NULL;
SomeWNDCLASS.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
SomeWNDCLASS.lpszMenuName = "MainWindowMenu";
SomeWNDCLASS.lpszClassName = SomeWNDCLASSName;

if ( !RegisterClass(&SomeWNDCLASS) )
{
MessageBox(NULL, "RegisterClass(&SomeWNDCLASS) failed", "Error!", MB_OK);
return FALSE;
}

TestWNDCLASS.style = CS_HREDRAW | CS_VREDRAW;
TestWNDCLASS.lpfnWndProc = DummyWindowProc;
TestWNDCLASS.cbClsExtra = 0;
TestWNDCLASS.cbWndExtra = 0;
TestWNDCLASS.hInstance = Instance;
TestWNDCLASS.hIcon = NULL;
TestWNDCLASS.hCursor = NULL;
TestWNDCLASS.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
TestWNDCLASS.lpszMenuName = NULL;
TestWNDCLASS.lpszClassName = TestWNDCLASSName;

if ( !RegisterClass(&TestWNDCLASS) )
{
MessageBox(NULL, "RegisterClass(&TestWNDCLASS) failed", "Error!", MB_OK);
return FALSE;
}

AnotherWNDCLASS.style = CS_HREDRAW | CS_VREDRAW;
AnotherWNDCLASS.lpfnWndProc = DummyWindowProc;
AnotherWNDCLASS.cbClsExtra = 0;
AnotherWNDCLASS.cbWndExtra = 0;
AnotherWNDCLASS.hInstance = Instance;
AnotherWNDCLASS.hIcon = NULL;
AnotherWNDCLASS.hCursor = NULL;
AnotherWNDCLASS.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
AnotherWNDCLASS.lpszMenuName = NULL;
AnotherWNDCLASS.lpszClassName = AnotherWNDCLASSName;

if ( !RegisterClass(&AnotherWNDCLASS) )
{
MessageBox(NULL, "RegisterClass(&AnotherWNDCLASS) failed", "Error!", MB_OK);
return FALSE;
}

MainWindow = CreateWindow
(
SomeWNDCLASSName,
MainWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
Instance,
0
);
if ( !MainWindow )
{
MessageBox(NULL, "CreateWindow() failed", "Error!", MB_OK);
return FALSE;
}

ShowWindow(MainWindow, nCmdShow);
UpdateWindow(MainWindow);

MSG msg;
while ( GetMessage(&msg, 0, 0, 0) )
{
DispatchMessage(&msg);
}

return TRUE;
}

HWND TestCreateWindow(void)
{
HWND TestWindow = CreateWindow
(
TestWNDCLASSName,
TestWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
Instance,
0
);
if ( !TestWindow )
{
return NULL;
}

ShowWindow(TestWindow, SW_SHOWNORMAL);
UpdateWindow(TestWindow);

return TestWindow;
}

HWND CreateAnotherWindow(void)
{
HWND AnotherWindow = CreateWindow
(
AnotherWNDCLASSName,
AnotherWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
Instance,
0
);
if ( !AnotherWindow )
{
return NULL;
}

ShowWindow(AnotherWindow, SW_SHOWNORMAL);
UpdateWindow(AnotherWindow);

return AnotherWindow;
}
---------------------------------- test.rc ----------------------------
#include <windows.h>
#include "test.h"

MainWindowMenu MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit" MWM_FILE_EXIT
END
POPUP "&Action"
BEGIN
MENUITEM "Test CreateWindow() &1" MWM_ACTION_TEST1_CREATEWINDOW
MENUITEM "Test CreateWindow() &2" MWM_ACTION_TEST2_CREATEWINDOW
END
POPUP "&Help"
BEGIN
MENUITEM "&About" MWM_HELP_ABOUT
END
END
------------------------------------ test.h -----------------------------
#define MWM_FILE_EXIT 0x0301
#define MWM_ACTION_TEST1_CREATEWINDOW 0x0401
#define MWM_ACTION_TEST2_CREATEWINDOW 0x0402
#define MWM_HELP_ABOUT 0x0501
-------------------------------------------------------------------------

результат работы данной прожки можно считать резюмой топика:
1) для win9x оба теста дают быстрый предсказанный результат -
повторяется использование хендла и закрывается НЕ ТО окно
2) при разработке NT-шной USER32.DLL эта ошибка видимо была учтена
добавлением случайного числа в старшее слово HWND и учете значения
этого слова при дальнейшей работе с HWND
я не дождался завала под NT4 - видимо практическая валидность под
этой системой высока

конкретную практическую валидность считайте для себя сами

зы: можно еще вспомнить такую штуку как PID - тоже ведь recycled и
reused и не где-нибудь а в хороших юниксах типа netBSD, Solaris etc.
программеры конечное же исходят из практической валидности числа
но надо только правильно ее оценивать
<programming>
[Win32] Виндос программеры - рассудите спор 13.02.02 17:55  
Автор: PS <PS> Статус: Elderman
Отредактировано 13.02.02 17:55  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
С коллегами спор возник.
Есть алгоритм:
1.Создаем окно
2.Запоминаем его hwnd
3.тра ля ля
4.закрываем окно по запомненому hwnd

Они утверждают, что алгоритм валиден. Я же говорю, что во время тра ла ла пользователь может закрыть окно, открыть какое нибудь другое и (внимание!) виндос даст новому окну тот же hwnd ! И тогда в п.4 мы закроем совсем не то окно какое следует.

Кто прав ?
[Win32] Обратимся к истокам 16.02.02 12:42  
Автор: 1blin Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
Platform SDK: Windows User Interface
IsWindow:

Remarks
An application should not use IsWindow for a window that it did not create because the window could be destroyed after this function was called. Further, because window handles are recycled the handle could even point to a different window.
[Win32] А алгоритм тем не менее валиден (в рамках области процесса)... 16.02.02 20:40  
Автор: LiNX Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
А по русски ? 17.02.02 22:35  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
В смысле в чем валидность ?
Этажем выше сказано было как раз то на чам я настаивал, - повторяться будут - закроем другое. Нет, зря я на пиво не спорил :)
резюме всего 17.02.02 22:57  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
рассмотрим два понимания ВАЛИДНОСТИ: теоретическую и практическую
теоретически алгоритм ИНВАЛИДЕН в принципе
чтобы не тратить попусту время приведу тестовую прожку,
доказывающую теоретическую ИНВАЛИДНОСТЬ алгоритма
--------------------------------- test.cpp ------------------------------
#include <windows.h>
#include <stdio.h>
#include "test.h"

HINSTANCE Instance;

HWND MainWindow;

HWND TestCreateWindow(void); // форвард
HWND CreateAnotherWindow(void); // форвард

char TestWNDCLASSName [] = "Test WNDCLASS name";
WNDCLASS TestWNDCLASS;
char TestWindowTitle [] = "Test window";

char AnotherWNDCLASSName [] = "Some WNDCLASS name";
WNDCLASS AnotherWNDCLASS;
char AnotherWindowTitle [] = "Some another window";

long WINAPI CALLBACK MainWindowProc
(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
HWND HWNDSavedByCoder;
switch (msg)
{
case WM_COMMAND:
{
switch (wParam)
{
case MWM_FILE_EXIT:
{
PostQuitMessage(0);
return 0;
}
case MWM_ACTION_TEST1_CREATEWINDOW:
{
// 1.Создаем окно
HWNDSavedByCoder = TestCreateWindow();
// 2.Запоминаем его hwnd
if (NULL != HWNDSavedByCoder)
{
// 3.тра ля ля
MessageBox(hWnd, "Please close manually [TEST WINDOW] and press OK to continue", "Your action here", MB_OK);
FILE* file = fopen("test.log", "wb");
fprintf(file,"HWNDSavedByCoder = %x\n", HWNDSavedByCoder);
for (;;)
{
HWND tempHWND = CreateAnotherWindow();
fprintf(file,"tempHWND = %x\n", tempHWND);
if (HWNDSavedByCoder == tempHWND)
{
MessageBox(tempHWND, "This really innocent window will now be destroyed", "look!", MB_OK);
break;
}
fflush(file);
}
// 4.закрываем окно по запомненому hwnd
DestroyWindow(HWNDSavedByCoder);
fclose(file);
Sleep(1000);
for(;;)
{
HWND tempHWND = GetForegroundWindow();
if (tempHWND == MainWindow) break;
DestroyWindow(tempHWND);
}
}
break;
}
case MWM_ACTION_TEST2_CREATEWINDOW:
{
// 1.Создаем окно
HWNDSavedByCoder = TestCreateWindow();
// 2.Запоминаем его hwnd
if (NULL != HWNDSavedByCoder)
{
// 3.тра ля ля
MessageBox(hWnd, "Please close manually [TEST WINDOW] and press OK to continue", "Your action here", MB_OK);
FILE* file = fopen("test.log", "wb");
fprintf(file,"HWNDSavedByCoder = %x\n", HWNDSavedByCoder);
for (;;)
{
HWND tempHWND = CreateAnotherWindow();
fprintf(file,"tempHWND = %x\n", tempHWND);
if (HWNDSavedByCoder == tempHWND)
{
MessageBox(tempHWND, "This really innocent window will now be destroyed", "look!", MB_OK);
break;
}
DestroyWindow(tempHWND);
fflush(file);
}
// 4.закрываем окно по запомненому hwnd
DestroyWindow(HWNDSavedByCoder);
fclose(file);
}
break;
}
case MWM_HELP_ABOUT:
{
MessageBox(hWnd, "www.BugTraq.ru/forum\ntest proggy by [z0]", "About", MB_OK);
break;
}
}
break;
}
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

long WINAPI CALLBACK DummyWindowProc
(
HWND hWnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain
(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
Instance = hInstance;

char SomeWNDCLASSName [] = "Main WNDCLASS name";
WNDCLASS SomeWNDCLASS;

char MainWindowTitle [] = "Main window";

SomeWNDCLASS.style = CS_HREDRAW | CS_VREDRAW;
SomeWNDCLASS.lpfnWndProc = MainWindowProc;
SomeWNDCLASS.cbClsExtra = 0;
SomeWNDCLASS.cbWndExtra = 0;
SomeWNDCLASS.hInstance = Instance;
SomeWNDCLASS.hIcon = NULL;
SomeWNDCLASS.hCursor = NULL;
SomeWNDCLASS.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
SomeWNDCLASS.lpszMenuName = "MainWindowMenu";
SomeWNDCLASS.lpszClassName = SomeWNDCLASSName;

if ( !RegisterClass(&SomeWNDCLASS) )
{
MessageBox(NULL, "RegisterClass(&SomeWNDCLASS) failed", "Error!", MB_OK);
return FALSE;
}

TestWNDCLASS.style = CS_HREDRAW | CS_VREDRAW;
TestWNDCLASS.lpfnWndProc = DummyWindowProc;
TestWNDCLASS.cbClsExtra = 0;
TestWNDCLASS.cbWndExtra = 0;
TestWNDCLASS.hInstance = Instance;
TestWNDCLASS.hIcon = NULL;
TestWNDCLASS.hCursor = NULL;
TestWNDCLASS.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
TestWNDCLASS.lpszMenuName = NULL;
TestWNDCLASS.lpszClassName = TestWNDCLASSName;

if ( !RegisterClass(&TestWNDCLASS) )
{
MessageBox(NULL, "RegisterClass(&TestWNDCLASS) failed", "Error!", MB_OK);
return FALSE;
}

AnotherWNDCLASS.style = CS_HREDRAW | CS_VREDRAW;
AnotherWNDCLASS.lpfnWndProc = DummyWindowProc;
AnotherWNDCLASS.cbClsExtra = 0;
AnotherWNDCLASS.cbWndExtra = 0;
AnotherWNDCLASS.hInstance = Instance;
AnotherWNDCLASS.hIcon = NULL;
AnotherWNDCLASS.hCursor = NULL;
AnotherWNDCLASS.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
AnotherWNDCLASS.lpszMenuName = NULL;
AnotherWNDCLASS.lpszClassName = AnotherWNDCLASSName;

if ( !RegisterClass(&AnotherWNDCLASS) )
{
MessageBox(NULL, "RegisterClass(&AnotherWNDCLASS) failed", "Error!", MB_OK);
return FALSE;
}

MainWindow = CreateWindow
(
SomeWNDCLASSName,
MainWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
Instance,
0
);
if ( !MainWindow )
{
MessageBox(NULL, "CreateWindow() failed", "Error!", MB_OK);
return FALSE;
}

ShowWindow(MainWindow, nCmdShow);
UpdateWindow(MainWindow);

MSG msg;
while ( GetMessage(&msg, 0, 0, 0) )
{
DispatchMessage(&msg);
}

return TRUE;
}

HWND TestCreateWindow(void)
{
HWND TestWindow = CreateWindow
(
TestWNDCLASSName,
TestWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
Instance,
0
);
if ( !TestWindow )
{
return NULL;
}

ShowWindow(TestWindow, SW_SHOWNORMAL);
UpdateWindow(TestWindow);

return TestWindow;
}

HWND CreateAnotherWindow(void)
{
HWND AnotherWindow = CreateWindow
(
AnotherWNDCLASSName,
AnotherWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
Instance,
0
);
if ( !AnotherWindow )
{
return NULL;
}

ShowWindow(AnotherWindow, SW_SHOWNORMAL);
UpdateWindow(AnotherWindow);

return AnotherWindow;
}
---------------------------------- test.rc ----------------------------
#include <windows.h>
#include "test.h"

MainWindowMenu MENU DISCARDABLE
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit" MWM_FILE_EXIT
END
POPUP "&Action"
BEGIN
MENUITEM "Test CreateWindow() &1" MWM_ACTION_TEST1_CREATEWINDOW
MENUITEM "Test CreateWindow() &2" MWM_ACTION_TEST2_CREATEWINDOW
END
POPUP "&Help"
BEGIN
MENUITEM "&About" MWM_HELP_ABOUT
END
END
------------------------------------ test.h -----------------------------
#define MWM_FILE_EXIT 0x0301
#define MWM_ACTION_TEST1_CREATEWINDOW 0x0401
#define MWM_ACTION_TEST2_CREATEWINDOW 0x0402
#define MWM_HELP_ABOUT 0x0501
-------------------------------------------------------------------------

результат работы данной прожки можно считать резюмой топика:
1) для win9x оба теста дают быстрый предсказанный результат -
повторяется использование хендла и закрывается НЕ ТО окно
2) при разработке NT-шной USER32.DLL эта ошибка видимо была учтена
добавлением случайного числа в старшее слово HWND и учете значения
этого слова при дальнейшей работе с HWND
я не дождался завала под NT4 - видимо практическая валидность под
этой системой высока

конкретную практическую валидность считайте для себя сами

зы: можно еще вспомнить такую штуку как PID - тоже ведь recycled и
reused и не где-нибудь а в хороших юниксах типа netBSD, Solaris etc.
программеры конечное же исходят из практической валидности числа
но надо только правильно ее оценивать
[Win32] Виндос программеры - рассудите спор 15.02.02 14:43  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
> С коллегами спор возник.
> Есть алгоритм:
> 1.Создаем окно
> 2.Запоминаем его hwnd
> 3.тра ля ля
> 4.закрываем окно по запомненому hwnd
>
> Они утверждают, что алгоритм валиден. Я же говорю, что во
> время тра ла ла пользователь может закрыть окно, открыть
> какое нибудь другое и (внимание!) виндос даст новому окну
> тот же hwnd ! И тогда в п.4 мы закроем совсем не то окно
> какое следует.
>
> Кто прав ?

нет не копались твои коллеги в виндах не понимают их специфики
линейные алгоритмы при работе с виндовс апи надо исключить напрочь
и кстати сами винды даже в ядре работают не по линейным а по спагетти-алгоритмам
в любой книжонке по программированию на первом же "хелло винды" видно как надо это делать:
1.создаем окно и прочую инициализацию проводим
2.входим в цикл обработки сообщений
и дальше все равно кто и как окно закроет - мышою, альт-ф4 или closewindow
там только написано что-то типа "смотрите как теперь удобно и просто стало" а надо было так сказать - "и попробуйте только по-другому..."

забавно что чем проще вещь тем труднее доходит
а вот отход от этого способа уже не забавен - действительно ведь не то окно совсем закроется

зы: ну конечно это не везде так - файловые операции например подчиняются линейности и хендлы там локальные
но в большинстве... все же это оболочка дешевая...
[Win32] Виндос программеры - рассудите спор 14.02.02 00:23  
Автор: ih8u <i hate you> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
када приходит @#$%ец окну - HWND тоже приходит @#$%ец!
если такое случилось, то нихуя работать не будет,
чего тут не ясного!!
[Win32] Виндос программеры - рассудите спор 15.02.02 14:52  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
> када приходит @#$%ец окну - HWND тоже приходит @#$%ец!
> если такое случилось, то нихуя работать не будет,
> чего тут не ясного!!

ну @#$%ец окну это допустим еще можно понять
а вот @#$%ец номеру записи в таблице окошек - честно скажу - не ясно
объяснишь?
[Win32] Виндос программеры - рассудите спор 17.02.02 12:45  
Автор: ih8u <i hate you> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
мля, когда окно умирает, HWND не будет принадлежать к какому либо окну, соответсвенно ты не сможешь его использовать, например, в SendMessage
[Win32] Виндос программеры - рассудите спор 13.02.02 22:24  
Автор: + <Mikhail> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> С коллегами спор возник.
> Есть алгоритм:
> 1.Создаем окно
> 2.Запоминаем его hwnd
> 3.тра ля ля
> 4.закрываем окно по запомненому hwnd
>
> Они утверждают, что алгоритм валиден. Я же говорю, что во
> время тра ла ла пользователь может закрыть окно, открыть
> какое нибудь другое и (внимание!) виндос даст новому окну
> тот же hwnd ! И тогда в п.4 мы закроем совсем не то окно
> какое следует.
>
> Кто прав ?
I dumau chto kollegi pravy:
Tak kak window handle global , to kogda okno destroyed eta handle invalid i tolko odin sposob dlia drugogo processa uznat` valid ili ne valid handle ispolzua IsWindow(hwnd). i esli pri sozdanii drugogo window mozhet ispolzovat`sia starai handle togda teriaetsia integriti WIndows.
Predstav` situaciu neskolko raznyh threads rabotaut s odnoi i toi zhe window, i esli Windows bydut recycle window handle togda bolshaia veroiatnost` chto chasto windows bydut putatsia, chego ne proishodit (mozhesh napisat` test application chtoby ubeditsia)
Я не в чем не ошибся ? 14.02.02 00:14  
Автор: PS <PS> Статус: Elderman
Отредактировано 14.02.02 00:15  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> I dumau chto kollegi pravy:
> Tak kak window handle global , to kogda okno destroyed eta
> handle invalid i tolko odin sposob dlia drugogo processa
> uznat` valid ili ne valid handle ispolzua IsWindow(hwnd).
> i esli pri sozdanii drugogo window mozhet ispolzovat`sia
> starai handle togda teriaetsia integriti WIndows.
> Predstav` situaciu neskolko raznyh threads rabotaut s odnoi
> i toi zhe window, i esli Windows bydut recycle window
> handle togda bolshaia veroiatnost` chto chasto windows
> bydut putatsia, chego ne proishodit (mozhesh napisat` test
> application chtoby ubeditsia)

Допустим одно окно создается за секунду. Тогда ((2^32)/60)/60 = 1193046 часов, Это 138 лет. Уменьшим создания окна с секунды. до 10мс, Тогда что бы выбрать все hwnd нам потребуется всего лишь год. Т.е. через год hwnd начнут повторяться... что-то многова-то...
Мда... вот что значит спорить не на трезвую голову. Хорошо хоть не на пиво.... :)
Windows 9X: The system can support a maximum of 16,364 window handles. 15.02.02 15:23  
Автор: z0 <z0> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
Там не 2^32, а много меньше 14.02.02 11:10  
Автор: ukv Статус: Незарегистрированный пользователь
<"чистая" ссылка> <обсуждение закрыто>
> Допустим одно окно создается за секунду. Тогда
> ((2^32)/60)/60 = 1193046 часов, Это 138 лет. Уменьшим
> создания окна с секунды. до 10мс, Тогда что бы выбрать все
> hwnd нам потребуется всего лишь год.

Не помню точно, но на 2^16 по-моему расчитывать можно, а больше - зависит от системы. Но 2^32 - и близко не будет.
Правильное решение - поставить hook на это окно и отслеживать его закрытие. Еще проще было бы получить нотификацию при закрытии окна, но по-моему нотификации идут только в parent.
2^16 14.02.02 11:56  
Автор: PS <PS> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Это 18 минут... значит я был прав. А правильно уже не сделаешь... Это огромный проект - фиг перепишишь. Остаеться только плеваться.
А по-моему хендёл у окна пожизненный 15.02.02 04:20  
Автор: Zef <Alloo Zef> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
Во первых: тот же Spy идентифицирует окна хендлами и я еще не замечал, чтобы в процессе жизни они менялись.
Во вторых: цикл обработки сообщений идентифицирует окна-адресаты по хендлам, и эти хендлы - СТАТИК.
В третьих: я где - то (чуть ли не у Питтрека) читал, что 2^16 хендлов - это мало, и я сам, похоже сталкивался с такой ситуацией: если какой-нит сайт начинает сыпать новые окна, как из пулемета - винда падает.
Я не в чем не ошибся ? 14.02.02 01:35  
Автор: Sandy <Alexander Stepanov> Статус: Elderman
<"чистая" ссылка> <обсуждение закрыто>
> Допустим одно окно создается за секунду. Тогда
> ((2^32)/60)/60 = 1193046 часов, Это 138 лет. Уменьшим
> создания окна с секунды. до 10мс, Тогда что бы выбрать все
> hwnd нам потребуется всего лишь год. Т.е. через год hwnd
> начнут повторяться... что-то многова-то...
> Мда... вот что значит спорить не на трезвую голову. Хорошо
> хоть не на пиво.... :)

Насколько я помню, хэндл (любой) - это смещение. Т.е., хэндл окна - смещение в таблице, описывающей ВСЕ имеющиеся окна в системе. На мой взгляд, нет ничего невозможного в ситуации, когда РАЗНЫМ окнам, существующим в РАЗНОЕ время, присваивается один и тот же хэндл.
1





Рейтинг@Mail.ru


  Copyright © 2001-2026 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach