This page is mostly for programmers who want to know how FKeys is put together. It's not very complicated. The basic idea is to be completely external to WriteLog and to minimize intrusive interactions.
The implementation is in Visual C++ using the MFC classes. At the top level it is a dialog box with a bunch of CButton controls in it (a CEdit for the scratchpad). The buttons are created dynamically at runtime based on the entries in the INI file.
Each time that the configuration might have changed the buttons are layed out and the window size is reset.
When a button is clicked we figure out which one it was then grab the command string from the INI file. Then it starts grabbing one command at a time, determines the type and then executes. Execution is where things get kind of different.
For Function Keys and Menu Commands a WM_COMMAND message is sent to the WriteLog main message queue. The WPARAM determines which function is executed (these are the numbers at the end of the FKeys.ini file).
For text the appropriate QsoEntryWnd is sent a WM_SYSCHAR Alt-K followed by the transmit command to WriteLog main message queue. The appropriate transmit window is moved to the Foreground and then there is a short delay (1 second first time 20 ms succeeding times). The delay allows the window to get opened. Then the text is sent to the window via a series of WM_CHAR messages. Finally, for CW the transmit window is hidden and for RTTY WM_SYSKEYDOWN Alt-K is sent to the window.
For macros there is specific code for each macro. Most are pretty straightforward, they require finding the right window and sending it an appropriate message.
Another interesting problem is finding the current QsoEntryWnd. The best I've been able to do is look through the candidates until I find one with a white pixel in the upper left corner. It is reliable as long as the upper left corner of the active entry window isn't covered by something else. Since it would be hard to operate with the entry window covered it probably will work.
The configuration utility redraws the buttons in a work area and duplicates all of the data structures for the commands. The WM_LBUTTONDOWN and WM_LBUTTONUP messages are processed to see if a button is being dragged. On BUTTONDOWN a CRectTracker is created and that is what the user drags around.
That's the short view of how it all works. If you'd like to see the code send me a note.