File "HotKeyMgr.bas"

Path: /HotKeyMgr/HotKeyMgr.bas
File size: 15.17 KB
MIME-type:
Charset: 8 bit


'-------------------------------------------------------------------------------------------------
#COMPILE EXE "HotKeyMgr.exe"
$VER = "1.1"
'-------------------------------------------------------------------------------------------------
#INCLUDE ONCE "Win32Api.inc"
#INCLUDE ONCE "inc\Julian.inc"
#INCLUDE ONCE "inc\SendInput.inc"
#INCLUDE ONCE "inc\AccentsMajuscules.inc"
#INCLUDE ONCE "inc\Highlighter.inc"
#INCLUDE ONCE "inc\ContactBook.inc"
#INCLUDE ONCE "inc\DatePicker.inc"
'-------------------------------------------------------------------------------------------------
#RESOURCE     "res\HotKeyMgr.pbr"
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
%MOD_ALT      = &H01
%MOD_CONTROL  = &H02
%WM_TRAYICON  = %WM_USER + 501
%IDM_Settings = %WM_USER + 502
%IDM_Activate = %WM_USER + 503
%IDM_Exit     = %WM_USER + 504
%IDM_Majus    = %WM_USER + 505
%IDM_Hilite   = %WM_USER + 506
%IDM_Calen    = %WM_USER + 507
%IDM_Email    = %WM_USER + 508
'-------------------------------------------------------------------------------------------------
GLOBAL hMain, hIcon, hMenu  AS DWORD
GLOBAL HotKeysEnabled       AS LONG
'-------------------------------------------------------------------------------------------------
MACRO INIFILE = EXE.PATH$ + EXE.NAME$ + ".ini"
MACRO PASTE   = SendString "{CTRL_D}v{CTRL_U}"
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
FUNCTION PBMAIN
    ' Allow only one instance
    LOCAL smutex AS STRING
    LOCAL x AS LONG
    smutex = EXE.NAME$                                      ' Mutex string
    x = CreateMutex(BYVAL %NULL, 0, BYVAL STRPTR(smutex))   ' check if running
    IF x <> %NULL THEN                                      ' Program probably already running ?
        IF GetLastError = %ERROR_ALREADY_EXISTS THEN        ' yes
            CloseHandle x                                   ' tidy up after, just to be polite
            EXIT FUNCTION
        END IF
    END IF

    ' Create main dialog (empty, will never show)
    DIALOG NEW 0, EXE.NAME$,,, 2, 2, %WS_SYSMENU _
        OR %WS_CAPTION OR %DS_MODALFRAME OR %WS_POPUP TO hMain
    hIcon = LoadIcon(GetModuleHandle(BYVAL 0&), "#5")
    SetClassLong(hMain, %GCL_HICONSM, hIcon)
    SetClassLong(hMain, %GCL_HICON, hIcon)

    DIALOG SHOW MODAL hMain CALL ProcMain
    DestroyIcon(hIcon)

END FUNCTION
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
SUB ReadPrefs()
    LOCAL zAsc AS ASCIIZ * %MAX_PATH
    LOCAL i AS LONG

    ' Read Date Picker output format - 'DateFormat' comes from 'DatePicker.inc'
    GetPrivateProfileString "date_picker", "output", "<b>w.dd/mm (Wwn)</b>", zAsc, %MAX_PATH, INIFILE
    DateFormat = TRIM$(zAsc)

    ' Read weekdays - shortWeekDay() and longWeekDay() come from 'Julian.inc'
    REDIM shortWeekDay(1 TO 7)
    REDIM longWeekDay(1 TO 7)
    FOR i = 1 TO 7
        GetPrivateProfileString "weekdays", "w("+TRIM$(STR$(i))+")", "", zAsc, %MAX_PATH, INIFILE
        shortWeekDay(i) = TRIM$(zAsc)
        GetPrivateProfileString "weekdays", "wd("+TRIM$(STR$(i))+")", "", zAsc, %MAX_PATH, INIFILE
        longWeekDay(i) = TRIM$(zAsc)
    NEXT

    ' Read months names - shortMonthName() and longMonthName() come from 'Julian.inc'
    REDIM shortMonthName(1 TO 12)
    REDIM longMonthName(1 TO 12)
    FOR i = 1 TO 12
        GetPrivateProfileString "months", "M("+TRIM$(STR$(i))+")", "", zAsc, %MAX_PATH, INIFILE
        shortMonthName(i) = TRIM$(zAsc)
        GetPrivateProfileString "months", "MM("+TRIM$(STR$(i))+")", "", zAsc, %MAX_PATH, INIFILE
        longMonthName(i) = TRIM$(zAsc)
    NEXT

END SUB
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
MACRO ENABLE_HOTKEYS
    RegisterHotKey CB.HNDL, nAtom(1), %MOD_CONTROL, ASC("M")          ' Register Ctrl-M (Accents Majuscule)
    RegisterHotKey CB.HNDL, nAtom(2), %MOD_CONTROL, ASC("D")          ' Register Ctrl-D (Date Picker)
    RegisterHotKey CB.HNDL, nAtom(3), %MOD_CONTROL+%MOD_ALT, ASC("0") ' Register @ key (Contact Book)
    RegisterHotKey CB.HNDL, nAtom(4), %MOD_CONTROL, ASC("H")          ' Register Ctrl-H (Highlight line)
END MACRO
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
MACRO DISABLE_HOTKEYS
    FOR i = 1 TO 4
        UnregisterHotKey CB.HNDL, nAtom(i)
    NEXT
END MACRO
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
CALLBACK FUNCTION ProcMain
  STATIC nAtom() AS DWORD
  STATIC ti      AS NOTIFYICONDATA
  LOCAL  i       AS LONG

  SELECT CASE CB.MSG

     CASE %WM_INITDIALOG
        ' Get/Create Settings
        IF NOT EXIST(INIFILE) THEN
            DumpStandardIniFile()
        END IF
        ReadPrefs()
        ' Register Hot Keys
        DIM nAtom(1 TO 4)
        nAtom(1) = GlobalAddAtom (EXE.NAME$ + "_1")     ' hk=1 -> Ctrl-M -> Accents Majuscule
        nAtom(2) = GlobalAddAtom (EXE.NAME$ + "_2")     ' hk=2 -> Ctrl-D -> Date Picker
        nAtom(3) = GlobalAddAtom (EXE.NAME$ + "_3")     ' hk=3 -> @ key  -> Contact Book
        nAtom(4) = GlobalAddAtom (EXE.NAME$ + "_4")     ' hk=4 -> Ctrl-H -> Highlight line
        ' Add tray icon
        ti.cbSize           = SIZEOF(ti)
        ti.hWnd             = CB.HNDL
        ti.uID              = GetModuleHandle(BYVAL 0&)
        ti.uFlags           = %NIF_ICON OR %NIF_MESSAGE OR %NIF_TIP
        ti.uCallbackMessage = %WM_TRAYICON
        ti.hIcon            = hIcon
        ti.szTip            = EXE.NAME$
        Shell_NotifyIcon %NIM_ADD, BYVAL VARPTR(ti)
        DestroyIcon ti.hIcon
        ' Create Popup Menu
        MENU NEW POPUP TO hMenu
        MENU ADD STRING,  hMenu, "Enable HotKey Manager",           %IDM_Activate,  %MF_ENABLED
        MENU SET STATE    hMenu,  BYCMD                             %IDM_Activate,  8 * HotKeysEnabled
        MENU ADD STRING,  hMenu, "-", 0, 0
        MENU ADD STRING,  hMenu, "Majuscules Accentues (Ctrl+M)",     %IDM_Majus,    %MF_ENABLED
        MENU ADD STRING,  hMenu, "Highlight line (Ctrl+H in OneNote)", %IDM_Hilite,   %MF_ENABLED
        MENU ADD STRING,  hMenu, "Date Picker (Ctrl+D in OneNote)",    %IDM_Calen,    %MF_ENABLED
        MENU ADD STRING,  hMenu, "Contact Book (@ key in OneNote)",    %IDM_Email,    %MF_ENABLED
        MENU ADD STRING,  hMenu, "-", 0, 0
        MENU ADD STRING,  hMenu, "Configure HotKeyMgr",                %IDM_Settings, %MF_ENABLED
        MENU ADD STRING,  hMenu, "Exit",                               %IDM_Exit,     %MF_ENABLED
        SetTimer CB.HNDL, 1, 0, %NULL       ' Hide main dialog
        IF ISTRUE ShowFirstRunBox() THEN    ' First Run Box contains a checkbox, returns true if checked
            HotKeysEnabled = %TRUE
            ENABLE_HOTKEYS
            MENU SET STATE hMenu, BYCMD %IDM_Activate, 8 * HotKeysEnabled
        END IF


     CASE %WM_DESTROY
        DISABLE_HOTKEYS
        FOR i = 1 TO 4
            GlobalDeleteAtom nAtom(i)
        NEXT
        Shell_NotifyIcon %NIM_DELETE, BYVAL VARPTR(ti)
        DestroyMenu hMenu

     CASE %WM_TIMER
        KillTimer CB.HNDL, 1
        ShowWindow CB.HNDL, 0

     CASE %WM_HOTKEY
        SLEEP 100
        FOR i = 1 TO 4
            IF CB.WPARAM = nAtom(i) THEN HandleHotKey i : EXIT FOR
        NEXT

     CASE %WM_TRAYICON                     ' User clicked on the systray icon
           LOCAL PA AS POINTAPI
           LOCAL mX, mY AS LONG
           mX = LOWRD(CB.LPARAM)
           IF mX = %WM_LBUTTONDOWN OR mX = %WM_RBUTTONDOWN THEN
               GetCursorPos PA
               mX = PA.X : mY = PA.Y
               SetForegroundWindow CB.HNDL ' needed to close popup menu when clicking outside
               TrackPopupMenu hMenu, %TPM_BOTTOMALIGN OR %TPM_RIGHTALIGN OR _
                              %TPM_LEFTBUTTON, mX, mY, 0, CB.HNDL, BYVAL %NULL
               PostMessage CB.HNDL, %WM_NULL, 0, 0
           END IF

    CASE %WM_COMMAND
      SELECT CASE AS LONG CB.CTL
        CASE %IDM_Majus
            HandleHotKey 11  ' Ctrl-M = Accents Majuscule
        CASE %IDM_Calen
            HandleHotKey 12  ' Ctrl-D = Date Picker
        CASE %IDM_Email
            HandleHotKey 13  ' @ key  = Contact Book
        CASE %IDM_Hilite
            HandleHotKey 14  ' Ctrl-H = Highlight line
        CASE %IDM_Settings
            ShellExecute 0, "open", INIFILE, "", "", %SW_SHOW
        CASE %IDM_Exit
            DIALOG END CB.HNDL
        CASE %IDM_Activate   ' Switch hotkey 'enabled' state
            IF ISTRUE HotKeysEnabled THEN
                HotKeysEnabled = %FALSE
                DISABLE_HOTKEYS
            ELSE
                HotKeysEnabled = %TRUE
                ENABLE_HOTKEYS
            END IF
            MENU SET STATE hMenu, BYCMD %IDM_Activate, 8 * HotKeysEnabled
      END SELECT

  END SELECT

END FUNCTION
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
SUB HandleHotKey(BYVAL hk AS LONG)
' hk=1 -> Ctrl-M -> Accents Majuscule
' hk=2 -> Ctrl-D -> Date Picker
' hk=3 -> @ key  -> Contact Book
' hk=4 -> Ctrl-H -> Highlight line

    LOCAL hWnd      AS DWORD
    LOCAL dlgCap    AS STRING
    LOCAL lRes      AS LONG

    ' Get active window + caption
    hWnd = GetForegroundWindow()
    DIALOG GET TEXT hWnd TO dlgCap

    ' Select Hot Key
    SELECT CASE AS LONG hk

        CASE 1, 11       ' Ctrl-M (anywhere) -> Accents Majuscule
            IF hk = 11 THEN hWnd = 0
            ShowMajus hWnd

        CASE 2, 12       ' Ctrl-D in OneNote -> Date Picker
            IF hk = 2 AND ISFALSE INSTR(dlgCap, "OneNote") THEN EXIT SUB
            IF hk = 12 THEN hWnd = 0
            ReadPrefs()                              ' read prefs (weekdays/months names) in case they changed...
            lRes = ShowDatePicker(hWnd)              ' show Date Picker dialog
            SetForegroundWindow hWnd
            IF lRes <> 0 THEN PASTE                  ' not cancelled > paste picked date in good format

        CASE 3, 13       ' @ key in OneNote  -> Contact Book
            IF hk = 3 AND ISFALSE INSTR(dlgCap, "OneNote") THEN
                SLEEP 150
                CLIPBOARD RESET
                CLIPBOARD SET TEXT "@"               ' if not in OneNote, write
                PASTE                                ' an '@' character, as
                EXIT SUB                             ' expected
            END IF
            IF hk = 13 THEN hWnd = 0
            lRes = ShowContactBook(hWnd)             ' else show Contact Book dialog
            SetForegroundWindow hWnd
            IF lRes <> 0 THEN PASTE                  ' not cancelled > paste chosen contact

        CASE 4, 14       ' Ctrl-H in OneNote -> Highlight line
            IF hk = 4 AND ISFALSE INSTR(dlgCap, "OneNote") THEN EXIT SUB
            IF hk = 14 THEN hWnd = 0
            lRes = ShowHighlight(hWnd)               ' show Highlighter dialog
            IF lRes <> 0 THEN
                SetForegroundWindow hWnd                 ' not cancelled > paste highlighted line
                SendString "{CTRL_D}v{CTRL_U}{END}{ESCAPE}"
            END IF

    END SELECT

END SUB
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
FUNCTION Get_Resource(BYVAL rid AS LONG) AS STRING
    LOCAL L1, L2 AS LONG
    LOCAL D1, D2 AS DWORD

    L1 = FindResource  (GetModuleHandle(""), "#"+FORMAT$(rid), BYVAL %RT_RCDATA)
    D2 = SizeofResource(GetModuleHandle(""), L1)
    L2 = LoadResource  (GetModuleHandle(""), L1)
    D1 = LockResource  (L2)

    FUNCTION = PEEK$(D1,D2)
END FUNCTION
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
SUB DumpStandardIniFile()
    LOCAL ff AS LONG
    KILL INIFILE
    ff = FREEFILE
    OPEN INIFILE FOR BINARY AS #ff
    PUT$ #ff, Get_Resource(10)      ' HotKeyMgr.ini
    CLOSE #ff
END SUB
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
CALLBACK FUNCTION ProcFirstRunBox
    LOCAL i AS LONG
    STATIC treated AS LONG
    IF (CB.MSG = %WM_COMMAND AND CB.CTL = %IDOK) OR (CB.MSG = %WM_DESTROY) THEN
        ' Enable Hotkeys?
        IF ISTRUE treated THEN EXIT FUNCTION
        treated = %TRUE
        CONTROL GET CHECK CB.HNDL, 1003 TO i
        DIALOG END CB.HNDL, i * -1
    END IF
END FUNCTION
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
FUNCTION ShowFirstRunBox() AS LONG
    LOCAL lRes AS LONG
    LOCAL hDlg AS DWORD

    DIALOG NEW PIXELS, 0, EXE.NAME$+$SPC+$VER,,, 270, 184, %WS_POPUP _
        OR %WS_BORDER OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR _
        %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
        %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT _
        OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
    DIALOG SET ICON hDlg, "#5"

    CONTROL ADD LABEL,    hDlg, 1001,   "Hot Key Manager is running in the notification zone :", 8, 8, 256, 16
    CONTROL ADD IMAGE,    hDlg, 1004,    "#104", 24, 32, 187, 31
    CONTROL ADD LABEL,    hDlg, 1002,   "Click on its icon to access the program options.", 8, 90, 256, 16
    CONTROL SET COLOR     hDlg, 1002,    RGB(0, 128, 128), -1
    CONTROL ADD CHECKBOX, hDlg, 1003,   " Catch Ctrl+M/D/H and @ key in OneNote", 8, 118, 256, 16
    CONTROL SET CHECK     hDlg, 1003,    1
    CONTROL ADD BUTTON,   hDlg, %IDOK,  "OK", 166, 150, 82, 24

    DIALOG SHOW MODAL   hDlg, CALL ProcFirstRunBox TO lRes
    FUNCTION = lRes
END FUNCTION
'-------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------
FUNCTION Exist(BYVAL fileOrFolder AS STRING) AS LONG
    LOCAL Dummy&
    Dummy& = GETATTR(fileOrFolder)
    FUNCTION = (ERRCLEAR = 0)
END FUNCTION
'-------------------------------------------------------------------------------------------------