When I was forced to change from Classic Outlook to New Outlook, I lost the ability to control the location of the notification window, which in turn made it hard to notice, and caused me to be late for some meetings. Here’s the story of how I fixed this.
The Problem
Classic Outlook would create a notification window by default. With new Outlook, I had to change the notification settings to get the same behavior; at least this was an option!
However, the notification window didn’t behave the same. With Classic Outlook, the notification window could be moved to the desired location, and would re-open in that same location when it was shown again. New Outlook doesn’t remember the position. Despite the settings stating that it would always appear in the center of the screen, it actually appears near the top-left of the screen. I run Outlook within a virtual machine, and typically some local window covers the top-left of the VM viewer window, so the notification window isn’t visible:-(
First Attempt at a Solution
To solve this, I needed some way to override the location of the notification window outside of Outlook. After some investigation, I found AutoHotkey, an automation tool for Windows. This tool has the ability to write scripts that perform many actions, such as searching for, moving, or setting the “always on top” attribute for a window.
Initially, I wrote the AutoHotkey script roughly as follows:
#Requires AutoHotkey v2.0
SetTitleMatchMode("RegEx")
TargetTitle := "Reminders - .* - Outlook"
loop {
hwnd := WinWait(TargetTitle)
WinMove(1270, 1270, , , hwnd)
WinSetAlwaysOnTop(1, hwnd)
}However, WinWait() only waits for a searched-for window to exist; it doesn’t
wait for a new window to be created. Thus, this solution works the first
time, but then continually finds the same window over and over, triggering
high CPU usage. What I needed was a way to detect when a new window was
created, or otherwise react to that event.
After more research I found the WinEvent library for AutoHotkey. This library will call a user-provided function whenever a specific event occurs.
The Final Solution
The final script is shown below. It installs a callback/event-handler for the “window shown” event. This function is called one time whenever a window is shown for the first time, thus avoiding the infinite loop mentioned above.
#Requires AutoHotkey v2.0
#include "WinEvent.ahk"
SetTitleMatchMode("RegEx")
TargetTitle := "Reminders - .* - Outlook"
WinEvent.Show(OnOutlookReminderCreated, TargetTitle)
OnOutlookReminderCreated(hWnd, hook, dwmsEventTime) {
WinMove(1270, 1270, , , hwnd)
WinSetAlwaysOnTop(1, hwnd)
}Save this as e.g. `Move Outlook Reminder Window.ahk’. Once the file is saved, it can be run directly (e.g. double-click it in Windows File Explorer) for testing purposes.
Automatic Startup
The final part of the solution was to cause the AutoHotkey script to run automatically each time the machine was rebooted, or I logged in. This is a simple matter of placing the script into the Windows startup folder, or at least placing a shortcut/link to the script into the startup folder. Here are some instructions to do that, cribbed from either Stack Overflow or the AutoHotkey forums.
- Locate your script: Find your
.ahkfile in File Explorer. - Create a shortcut: Right-click the script and select Create shortcut.
- Open the Startup folder: Press Win + R, type explorer, and hit Enter. In the URL/location bar, enter
shell:startup. - Move the shortcut: Drag or paste the newly created shortcut into this folder.