Каково время жизни CWnd, полученного из CWnd :: FromHandle? - PullRequest
12 голосов
/ 01 октября 2009

Согласно msdn , когда я получаю CWnd * с CWnd :: FromHandle,

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

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

Ответы [ 4 ]

15 голосов
/ 01 октября 2009

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

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

1 голос
/ 01 октября 2009

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

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

-Ron

0 голосов
/ 01 октября 2009

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

0 голосов
/ 01 октября 2009

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

...