Какова продолжительность жизни CWnd, полученной из CWnd:: FromHandle?

В соответствии с msdn, когда я получить CWnd * с CWnd:: FromHandle,

Указатель может быть временным и не должен храниться для последующего использования.

То, что подразумевается под "более поздним использованием", мне непонятно. Это только область действия текущего метода? Насколько я знаю, в Win32 нет GC!

Ответ 1

MFC поддерживает несколько карт дескрипторов: от HWND до CWnd, HDC до CDC и т.д., которые хранятся в состоянии потока. Каждая карта ручек содержит постоянную карту, а временная карта - постоянные записи добавляются при вызове метода, такого как CWnd:: Create или CDC:: Attach, тогда как временные записи создаются при вызове FromHandle на дескрипторе, который не имеет постоянная запись.

Временные записи очищаются во время обработки бездействия (в CWinApp:: OnIdle), поэтому их можно безопасно использовать только при обработке текущего сообщения. Как только вы вернетесь в цикл сообщений или введите другой модальный цикл (например, вызывая DoModal), они могут быть удалены.

Ответ 2

FromHandle в основном используется для получения временной ссылки на уже существующий объект окна. MFC хранит эти ссылки во внутренней структуре, называемой временной картой дескриптора (карта дескриптора представляет собой карту Windows HWND для объектов MFC CWnd, используемых MFC, чтобы заставить вызовы Win32 манипулировать фактическим окном Windows, которому соответствует объект MFC). Чтобы избежать увеличения количества объектов в этой структуре за пределами всех границ, элементы удаляются из карты дескриптора во время обработки цикла холостого хода MFC.

Как вы, возможно, догадались, есть также постоянная карта ручек, которая не будет иметь этого автоматического режима очистки. Если вам нужно получить объект CWnd, который не помещает его ссылку HWND во временную карту дескриптора, вы можете вызвать FromHandlePermanent().

-Ron

Ответ 3

Основываясь на том же описании MSDN, я бы предположил, что это означает, что если ни один CWnd не присоединен к hWnd, предоставленному как объект, он создаст временную CWnd, которая, вероятно, будет уничтожена, когда что-то выходит из сферы действия, или деструктор в другом месте, или CWnd явно создается для рассматриваемого hWnd. Итак, если у вас уже есть CWnd, вы должны быть в порядке, иначе вам, вероятно, нужно быть очень осторожным с сохранением указателя, который вы получаете.

Ответ 4

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