# DestroyWindow() non-existant windows

What I am working on has sets of window controls. Controls are constantly being either destroyed, or created.

void ChangeControl() {

// remove all controls, existing, or not
hwnd = GetDlgItem(hWnd, IDC_BTN_FOOA);
DestroyWindow(hwnd);
hwnd = GetDlgItem(hWnd, IDC_BTN_FOOB);
DestroyWindow(hwnd);
hwnd = GetDlgItem(hWnd, IDC_BTN_FOOC);

hwndButton = CreateWindow("BUTTON", "Start", WS_VISIBLE|WS_CHILD|BS_OWNERDRAW|BS_PUSHBUTTON,
left, top, BUTTON_WIDTH, BUTTON_HEIGHT, hWnd, (HMENU)IDC_BTN_FOOB, GetModuleHandle(NULL), NULL);
}


Test case:

DWORD errorResult;
testHwnd = GetDlgItem(hWnd, IDC_BTN_START);
if (testHwnd) {
DestroyWindow(hwnd);
}
else {
errorResult = GetLastError();
}


I am wondering if this method is safe, or if I should be checking if a control exists before calling DestroyWindow().

• Can you rig up a test to pass DestroyWindow a junk handle and then read GetLastError? That might let you know how safe it is. – Mike Sep 11 '14 at 19:56

If the control doesn't exist then GetDlgItem returns NULL. Passing NULL to DestroyWindow should be "save" in the sense that it won't crash - it will return FALSE and GetLastError will be returning an "Invalid Handle" error (or something like that) (can't find any docs for it but that's the behaviour I've seen in the past).

hwnd = GetDlgItem(hWnd, IDC_BTN_FOOA);

The use of two different variables which only differ in the capitalization of a single letter is ugly and error prone and you should use a different name. One convention I tend to follow if I select objects which are to be destroyed is to call them doomed. So maybe something like this:
doomedHandle = GetDlgItem(hWnd, IDC_BTN_FOOA);

• @EvanCarslake: I'm pretty sure GetLastError() doesn't reset the error code. To my knowledge the error code is only change when SetLastError() is called. – ChrisWue Sep 13 '14 at 2:17