| 5668 | |
| 5669 | |
| 5670 | VOID CALLBACK InputBoxTimeout(HWND hWnd, UINT uMsg, UINT idEvent, DWORD dwTime) |
| 5671 | { |
| 5672 | // First check if the window has already been destroyed. There are quite a few ways this can |
| 5673 | // happen, and in all of them we want to make sure not to do things such as calling EndDialog() |
| 5674 | // again or updating the output variable. Reasons: |
| 5675 | // 1) The user has already pressed the OK or Cancel button (the timer isn't killed there because |
| 5676 | // it relies on us doing this check here). In this case, EndDialog() has already been called |
| 5677 | // (with the proper result value) and the script's output variable has already been set. |
| 5678 | // 2) Even if we were to kill the timer when the user presses a button to dismiss the dialog, |
| 5679 | // this IsWindow() check would still be needed here because TimerProc()'s are called via |
| 5680 | // WM_TIMER messages, some of which might still be in our msg queue even after the timer |
| 5681 | // has been killed. In other words, split second timing issues may cause this TimerProc() |
| 5682 | // to fire even if the timer were killed when the user dismissed the dialog. |
| 5683 | // UPDATE: For performance reasons, the timer is now killed when the user presses a button, |
| 5684 | // so case #1 is obsolete (but kept here for background/insight). |
| 5685 | if (IsWindow(hWnd)) |
| 5686 | { |
| 5687 | // This is the element in the array that corresponds to the InputBox for which |
| 5688 | // this function has just been called. |
| 5689 | int target_index = idEvent - INPUTBOX_TIMER_ID_OFFSET; |
| 5690 | // Even though the dialog has timed out, we still want to write anything the user |
| 5691 | // had a chance to enter into the output var. This is because it's conceivable that |
| 5692 | // someone might want a short timeout just to enter something quick and let the |
| 5693 | // timeout dismiss the dialog for them (i.e. so that they don't have to press enter |
| 5694 | // or a button: |
| 5695 | HWND hControl = GetDlgItem(hWnd, IDC_INPUTEDIT); |
| 5696 | if (hControl) |
| 5697 | { |
| 5698 | #undef INPUTBOX_VAR |
| 5699 | #define INPUTBOX_VAR (g_InputBox[target_index].output_var) |
| 5700 | VarSizeType space_needed = GetWindowTextLength(hControl) + 1; |
| 5701 | // Set up the var, enlarging it if necessary. If the output_var is of type VAR_CLIPBOARD, |
| 5702 | // this call will set up the clipboard for writing: |
| 5703 | if (INPUTBOX_VAR->Assign(NULL, space_needed - 1) == OK) |
| 5704 | { |
| 5705 | // Write to the variable: |
| 5706 | INPUTBOX_VAR->Length() = (VarSizeType)GetWindowText(hControl |
| 5707 | , INPUTBOX_VAR->Contents(), space_needed); |
| 5708 | if (!INPUTBOX_VAR->Length()) |
| 5709 | // There was no text to get or GetWindowText() failed. |
| 5710 | *INPUTBOX_VAR->Contents() = '\0'; // Safe because Assign() gave us a non-constant memory area. |
| 5711 | INPUTBOX_VAR->Close(); // In case it's the clipboard. |
| 5712 | } |
| 5713 | } |
| 5714 | EndDialog(hWnd, AHK_TIMEOUT); |
| 5715 | } |
| 5716 | KillTimer(hWnd, idEvent); |
| 5717 | } |
| 5718 | |
| 5719 | |
| 5720 | |