2 * Openwide -- control Windows common dialog
4 * Copyright (c) 2000 Luke Hudson
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 /* --- The following code comes from c:\lcc\lib\wizard\dll.tpl. */
32 #include "openwidedll.h"
33 #include "openwidedllres.h"
35 #include "owSharedUtil.h"
38 // DLL Instance handle
39 HINSTANCE ghInst
= NULL
;
41 // Handle to shared memory access locking mutex.
42 HANDLE ghMutex
= NULL
;
43 POWSharedData gpSharedMem
= NULL
; // pointer to shared mem
44 // Handle to filemapping for shared mem
46 // System hook handles
47 HHOOK ghMsgHook
= NULL
, ghSysMsgHook
= NULL
;
49 // This cache is refreshed -- TODO: When?
50 OWSharedData gOwShared
; // stores copy of shared mem for access to non-pointer datas without extended blocking
54 /* Add an icon to the toolbar within the O&S Dialogs
55 * @param hwTB -- toolbar handle
56 * @param hIcn -- icon handle
58 * @returns -1 on error, or the index of the new icon within the imagelist.
60 int addIcon2TB(HWND hwTB
, HICON hIcn
)
62 HIMAGELIST hImgList
= NULL
;
63 hImgList
= (HIMAGELIST
)SendMessage(hwTB
, TB_GETIMAGELIST
, 0, 0);
66 // int nImgs = ImageList_GetImageCount(hImgList);
67 int idxNew
= ImageList_AddIcon(hImgList
, hIcn
);
70 //dbg("%s, Error adding to imglist: %s", __func__, geterrmsg());
75 //dbg("%s, Image added at index %d", __func__, idxNew);
76 SendMessage(hwTB
, TB_SETIMAGELIST
, 0, (LPARAM
)hImgList
);
85 * Adds a new button to the toolbar : hwnd
87 * @param hwnd -- parent window of toolbar, ie. the O&S Dialog.
89 * @returns 1 -- TODO: this should return 0 on error, but doesn't appear to.
91 static int addTBButton(HWND hwnd
)
93 // Locate the toolbar handle.
94 HWND hwTB
= findChildWindow(hwnd
, CID_TOOLBAR
, TOOLBARCLASSNAME
);
96 // Create toolbar button structure
98 tb
.iBitmap
= VIEW_NETCONNECT
;
100 // Load the toolbar icon, and add it to the imagelist, retaining the index.
102 HICON hIcn
= (HICON
)LoadImage(ghInst
, MAKEINTRESOURCE(IDI_TBICON
), IMAGE_ICON
, 16, 16, 0);
105 idxNew
= addIcon2TB(hwTB
, hIcn
);
109 tb
.iBitmap
= idxNew
; // set button image index
110 tb
.idCommand
= OW_TBUTTON_CMDID
; // set command id -- @see openwidedll.h
111 // Set the button style flags
112 tb
.fsStyle
= BTNS_AUTOSIZE
| BTNS_BUTTON
| BTNS_SHOWTEXT
| BTNS_DROPDOWN
; // BTNS_WHOLEDROPDOWN;
113 // Set the button state flags
114 tb
.fsState
= TBSTATE_ENABLED
;
115 // And give it a tooltip ? TODO: Check this
116 tb
.iString
= (INT_PTR
)"OpenWide by Lingo";
118 SendMessage(hwTB
, TB_ADDBUTTONS
, 1, (LPARAM
) & tb
);
120 // Ensure that the toolbar window is large enough to show the new button.
122 int idxLast
= SendMessage(hwTB
, TB_BUTTONCOUNT
, 0, 0) - 1;
123 if (SendMessage(hwTB
, TB_GETITEMRECT
, idxLast
, (LPARAM
) & r
))
126 GetWindowRect(hwTB
, &rw
);
127 MapWindowPoints(hwTB
, NULL
, (LPPOINT
) & r
, 2);
128 SetWindowPos(hwTB
, NULL
, 0, 0, (r
.right
+ 8) - rw
.left
, rw
.bottom
- rw
.top
+ 1, SWP_NOMOVE
| SWP_NOZORDER
);
131 } // END of addTBButton(...)
134 * Show a drop-down menu from the toolbar button.
136 * @param hwnd -- O&S dialog
137 * @param hwTB -- toolbar handle
138 * @param uiItem -- id of toolbar item ? -- TODO: Check this.
140 static void dropMenu(HWND hwnd
, HWND hwTB
, UINT uiItem
)
143 // Get the screen coords rectangle of the button
144 SendMessage(hwTB
, TB_GETRECT
, uiItem
, (LPARAM
) & r
);
145 MapWindowPoints(hwTB
, NULL
, (LPPOINT
) & r
, 2);
147 // Set the area for the menu to avoid. ? :: TODO: see Platform SDK on TrackPopupMenuEx
148 TPMPARAMS tpm
= { 0 };
149 tpm
.cbSize
= sizeof(tpm
);
152 // Create the menu structure.
153 HMENU hm
= CreatePopupMenu();
154 AppendMenu(hm
, MF_STRING
, OW_EXPLORE_CMDID
, "&Locate current folder with Explorer...");
155 AppendMenu(hm
, MF_STRING
, OW_SHOWDESK_CMDID
, "Show &Desktop [for Gabriel]...");
156 AppendMenu(hm
, MF_SEPARATOR
| MF_DISABLED
, 0, NULL
);
157 AppendMenu(hm
, MF_STRING
, OW_ABOUT_CMDID
, "&About OpenWide...");
158 SetMenuDefaultItem(hm
, OW_SHOWDESK_CMDID
, FALSE
);
160 // * This section is todo with having Favourite directories, and is unfinished.
162 AppendMenu(hm, MF_STRING, OW_ADDFAV_CMDID, "Add &Favourite");
163 SetMenuDefaultItem(hm, OW_ADDFAV_CMDID, FALSE);
164 POWSharedData pow = lockSharedData();
167 dbg("%s, Locked shared data ok", __func__);
168 PFavLink pFav = pow->pFaves;
171 MENUITEMINFO mii = { 0 };
172 mii.cbSize = sizeof(mii);
173 AppendMenu(hm, MF_SEPARATOR | MF_DISABLED, 0, NULL);
174 for (int i = 0; i < pow->nFaves; i++)
176 pFav = getNthFave(pow, i);
179 static char szBuf[MAX_PATH + 8];
181 dbgLink("inserting...", pFav);
182 mii.fMask = MIIM_STRING | MIIM_DATA | MIIM_ID;
183 mii.fType = MFT_STRING;
184 wsprintf(szBuf, "%s\tCtrl+%d", pFav->szFav, (pFav->idCmd - OW_FAVOURITE_CMDID) + 1);
185 mii.dwTypeData = szBuf;
186 mii.dwItemData = pFav->idCmd;
187 mii.wID = pFav->idCmd;
189 int iRes = InsertMenuItem(hm, -1, TRUE, &mii);
191 dbg("%s, Failed inserting item: %s", __func__, geterrmsg());
192 //idx = AppendMenu(hm, MF_STRING, iCmd++, pFav->szFav);
195 unlockSharedData(pow);
198 // Display, track, then destroy the menu.
199 TrackPopupMenuEx(hm
, TPM_HORIZONTAL
| TPM_RIGHTALIGN
| TPM_LEFTBUTTON
| TPM_VERTICAL
, r
.right
, r
.bottom
, hwnd
, &tpm
);
201 } // END of dropMenu(...)
205 // add a new 'place' into the Places bar.
206 int addPlace(HWND hwnd, PFavLink plk)
208 HWND hwTB = GetDlgItem(hwnd, CID_PLACES);
211 tb.iBitmap = giPlacesIcon;
212 tb.idCommand = plk->idCmd;
213 tb.fsStyle = BTNS_BUTTON | BTNS_SHOWTEXT; // BTNS_WHOLEDROPDOWN;
214 tb.fsState = TBSTATE_ENABLED;
215 tb.iString = (INT_PTR)PathFindFileName(plk->szFav);
216 SendMessage(hwTB, TB_ADDBUTTONS, 1, (LPARAM) & tb);
221 // Add a new favourite dir, first retrieving the path from the current view of the O&S dialog.
223 int addFavourite(HWND hwnd)
225 //static char szBuf[2*MAX_PATH+1];
226 assert( IsWindow(hwnd));
228 char *szBuf = (char *)GlobalAlloc(GPTR, 2 * MAX_PATH + 1);
231 if( SendMessage(hwnd, CDM_GETFOLDERPATH, 2*MAX_PATH, (LPARAM)szBuf) > 0 )
233 if( !faveExists(szBuf) )
235 PFavLink plNew = newFav(szBuf);
237 addPlace(hwnd, plNew);
239 dbg("%s, failed to create new fave", __func__);
242 dbg("%s, Fave: '%s' exists already", __func__, szBuf);
251 * Given the handle to the O&S dialog, this does the magic to it, such as
252 * adding toolbar buttons, setting the focus and view mode, and adding items to
255 * @returns 1, TODO:: There should be error indication, perhaps!
257 int openWide(HWND hwnd
)
260 int w
= gOwShared
.szDim
.cx
;
261 int h
= gOwShared
.szDim
.cy
;
262 int x
= gOwShared
.ptOrg
.x
;
263 int y
= gOwShared
.ptOrg
.y
;
264 SetWindowPos(hwnd
, NULL
, x
, y
, w
, h
, SWP_NOZORDER
);
267 HWND hwDirCtl
= GetDlgItem(hwnd
, CID_DIRLISTPARENT
);
268 WORD vCmdID
= viewToCmdID(gOwShared
.iView
);
269 // set the view mode, by sending a fake command message.
270 SendMessage(hwDirCtl
, WM_COMMAND
, MAKEWPARAM(vCmdID
, 0), 0);
273 focusDlgItem(hwnd
, gOwShared
.iFocus
);
276 // debug hook, to find menu cmd IDs
277 dbg("Hooking SYSMSG...");
278 ghSysMsgHook
= SetWindowsHookEx(
282 0 //GetCurrentThreadId() // Only install for THIS thread!!!
284 dbg("Hooking returned %p", ghSysMsgHook
);
286 // Allow drag&drop onto window. Unfortunately this doesn't work for the
287 // directory list, as that is already set to accept drops, as a command to
288 // copy/move files. I would have to subclass this too, and that's rather
290 DragAcceptFiles(hwnd
, TRUE
);
292 // Insert item into the system menu (right-click on titlebar)
293 HMENU hm
= GetSystemMenu(hwnd
, FALSE
);
294 AppendMenu(hm
, MF_SEPARATOR
| MF_DISABLED
, 0, NULL
);
295 AppendMenu(hm
, MF_STRING
, OW_EXPLORE_CMDID
, "&Locate current folder with Explorer...");
296 AppendMenu(hm
, MF_STRING
, OW_ABOUT_CMDID
, "&About OpenWide...");
298 addTBButton(hwnd
); // add the toolbar button.
300 // Modify the dir-list view flags
301 HWND hwShellCtl = GetDlgItem(hwnd, CID_DIRLISTPARENT);
302 hwShellCtl = GetDlgItem(hwShellCtl, 1);
303 ListView_SetExtendedListViewStyleEx(hwShellCtl, OW_LISTVIEW_STYLE, OW_LISTVIEW_STYLE );
306 } // END openWide(...)
309 /* Load the desktop folder into the dir list */
310 void showDesktop(HWND hwnd
)
312 char * szDesk
= GlobalAlloc(GPTR
, MAX_PATH
+1);
313 if( szDesk
&& SHGetSpecialFolderPath(hwnd
, szDesk
, CSIDL_DESKTOPDIRECTORY
,FALSE
) )
315 char *szOld
= getDlgItemText(hwnd
, CID_FNAME
);
316 SetDlgItemText(hwnd
, CID_FNAME
, szDesk
);
317 SendDlgItemMessage(hwnd
, CID_FNAME
, EM_SETSEL
, -1, -1);
318 SendDlgItemMessage(hwnd
, CID_FNAME
, EM_REPLACESEL
, FALSE
, (LPARAM
)"\\");
319 SendMessage(hwnd
, WM_COMMAND
, MAKEWPARAM(IDOK
, BN_CLICKED
), (LPARAM
)GetDlgItem(hwnd
, IDOK
));
321 SetDlgItemText(hwnd
, CID_FNAME
, szOld
);
323 SetDlgItemText(hwnd
, CID_FNAME
, "");
331 * This is the callback for the subclassed O&S dialog window, and it handles
332 * all the extra functionality, passing along messages to the old callback
333 * function unless the behaviour is modified.
336 LRESULT CALLBACK WINAPI
wpSubMain(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
340 dbgWM(hwnd, msg, wp, lp);
343 // retrieve a ptr to the extra information associated with the window.
344 POWSubClassData pow
= (POWSubClassData
)GetProp(hwnd
, OW_PROP_NAME
);
346 return DefWindowProc(hwnd
, msg
, wp
, lp
); // something's broken, so just allow default window function.
348 static char buffer
[MAX_PATH
+1];
354 // dbg("DLL: INITDIALOG");
355 LRESULT lRes
= CallWindowProc(pow
->wpOrig
, hwnd
, msg
, wp
, lp
); // call the old callback
356 ShowWindow(hwnd
, SW_HIDE
); // hide the window, until it's been magick-ed by openWide(...)
362 if( wp
&& !pow
->bSet
) // catch the first SHOWWINDOW only,
369 case WM_COMMAND
: // handle custom toolbar button commands, etc.
372 case OW_ABOUT_CMDID
: // about
373 MessageBox(hwnd
, "OpenWide is written by Luke Hudson. (c)2005", "About OpenWide", MB_OK
);
375 // show desktop item, or click on button rather than
376 // dropdown (ie, defaults to show desktop menuitem)
377 case OW_TBUTTON_CMDID
:
378 case OW_SHOWDESK_CMDID
:
381 case OW_EXPLORE_CMDID
: // Explore current dir in new Explorer window
383 // Build a command line
384 char *szParm
= "/select,";
385 wsprintf(buffer
, szParm
);
386 int len
= strlen(szParm
);
387 LPARAM lpBuf
= (LPARAM
)buffer
+ (LPARAM
)len
;
388 //dbg("CDM_GET..PATH, cbSize=%d, buffer = %p", MAX_PATH-len, lpBuf);
389 len
= SendMessage(hwnd
, CDM_GETFOLDERPATH
, MAX_PATH
- len
, lpBuf
); //(LPARAM)(char *)((unsigned int)buffer + (unsigned int)len));
392 // execute the command line
393 ShellExecute(hwnd
, NULL
, "explorer.exe", buffer
, NULL
, SW_SHOWNORMAL
);
398 // Handling of favourites -- UNFININSHED
399 case OW_ADDFAV_CMDID:
403 if (LOWORD(wp) >= OW_FAVOURITE_CMDID)
405 getFavourite(hwnd, (int)LOWORD(wp));
408 } // switch : command ids
411 // Handle notifications from the toolbar
414 NMHDR
*phdr
= (NMHDR
*)lp
;
415 HWND hwTB
= findChildWindow(hwnd
, CID_TOOLBAR
, TOOLBARCLASSNAME
);
416 if (phdr
->hwndFrom
== hwTB
)
418 // dbg("Got notify %d from toolbar", phdr->code);
419 if (phdr
->code
== TBN_DROPDOWN
)
421 NMTOOLBAR
*ptb
= (NMTOOLBAR
*)lp
;
422 if (ptb
->iItem
== OW_TBUTTON_CMDID
)
424 dropMenu(hwnd
, hwTB
, ptb
->iItem
);
425 return TBDDRET_DEFAULT
;
432 // handle notifications from the dir listview control
433 case WM_PARENTNOTIFY
:
434 if( LOWORD(wp
) == WM_CREATE
)
437 GetClassName((HWND
)lp
, buf
, 32);
439 if( strcmp(buf
, "SHELLDLL_DefView") == 0 )
441 // dbg("Shell defview ctl created");
442 // subclass((HWND)lp, wpSubShellCtl, (LPARAM)hwnd);
443 HWND hwLV
= GetDlgItem((HWND
)lp
, 1);
446 if( GetWindowLong(hwLV
, GWL_STYLE
) & LVS_REPORT
) // if details view is in effect.
448 // update style flags
449 ListView_SetExtendedListViewStyleEx(hwLV
, OW_LISTVIEW_STYLE
, OW_LISTVIEW_STYLE
);
450 // Send Control+NumpadPlus to expand all the columns to fit contents
452 in
[0].type
= INPUT_KEYBOARD
;
453 in
[0].ki
.wVk
= VK_CONTROL
;
454 in
[1].type
= INPUT_KEYBOARD
;
455 in
[1].ki
.wVk
= VK_ADD
;
456 in
[2].type
= INPUT_KEYBOARD
;
457 in
[2].ki
.wVk
= VK_CONTROL
;
458 in
[2].ki
.dwFlags
= KEYEVENTF_KEYUP
;
459 in
[3].type
= INPUT_KEYBOARD
;
460 in
[3].ki
.wVk
= VK_ADD
;
461 in
[3].ki
.dwFlags
= KEYEVENTF_KEYUP
;
462 HWND hwOld
= SetFocus(hwLV
);
463 SendInput(4, in
, sizeof(INPUT
));
467 //SetTimer(hwnd, 251177, 1, NULL); // set a timer, for what? TODO:: Check this
471 /// Deprecated -- I think? TODO: Check
475 KillTimer(hwnd, 251177);
476 HWND hwDirCtl = GetDlgItem(hwnd, CID_DIRLISTPARENT);
477 if( getSharedData() )
479 if( gOwShared.iView == V_THUMBS || gOwShared.iView == V_TILES )
481 // dbg("posting cmd message to reset view?");
482 WORD vCmdID = viewToCmdID(gOwShared.iView);
483 PostMessage(hwDirCtl, WM_COMMAND, MAKEWPARAM(vCmdID, 0), 0);
489 case WM_SYSCOMMAND
: // Handle system menu commands
491 int cmdId
= wp
& 0xFFF0;
492 if( cmdId
== OW_ABOUT_CMDID
)
494 MessageBox(hwnd
, "OpenWide is written by Luke Hudson. (c)2005", "About OpenWide", MB_OK
);
497 else if( cmdId
== OW_EXPLORE_CMDID
)
499 char * szParm
= "/select,";
500 wsprintf(buffer
, szParm
);
501 int len
= strlen(szParm
);
502 len
= SendMessage(hwnd
, CDM_GETFOLDERPATH
, MAX_PATH
-len
, (LPARAM
)(buffer
+len
));
505 ShellExecute(hwnd
, NULL
, "explorer.exe", buffer
, NULL
, SW_SHOWNORMAL
);
510 /* case WM_NCPAINT: // handle painting of non-content area, ie. window titlebar and frame.
512 HDC hdc = GetWindowDC(hwnd);
515 hbrOld = SelectObject(hdc, GetStockObject(BLACK_BRUSH));
516 hpOld = SelectObject(hdc, GetStockObject(NULL_PEN));
518 GetWindowRect(hwnd, &r);
523 RoundRect(hdc, r.left, r.top, r.right, r.bottom, 16,16);
524 SelectObject(hdc, hbrOld);
525 SelectObject(hdc, hpOld);
526 ReleaseDC(hwnd, hdc);
529 case WM_DROPFILES
: // Handle files which are dragged&dropped onto window.
531 HANDLE hDrop
= (HANDLE
)wp
;
532 int nFiles
= DragQueryFile(hDrop
, (UINT
)-1, NULL
, 0);
535 if( DragQueryFile(hDrop
, 0, buffer
, MAX_PATH
) )
537 if( PathIsDirectory(buffer
) )
539 // Set the view to dropped directory path.
540 SetDlgItemText(hwnd
, CID_FNAME
, buffer
);
541 SendDlgItemMessage(hwnd
, CID_FNAME
, EM_SETSEL
, -1, -1);
542 SendDlgItemMessage(hwnd
, CID_FNAME
, EM_REPLACESEL
, FALSE
, (LPARAM
)"\\");
543 SendMessage(hwnd
, WM_COMMAND
, MAKEWPARAM(IDOK
, BN_CLICKED
), (LPARAM
)GetDlgItem(hwnd
, IDOK
));
544 SetDlgItemText(hwnd
, CID_FNAME
, "");
545 if( getSharedData() )
547 focusDlgItem(hwnd
, gOwShared
.iFocus
);
556 //dbg("DLL: DESTROY");
557 if( openSharedMem() )
559 //dbg("DLL: Opened shared memory");
560 if( --gpSharedMem
->refCount
< 0 ) // Update the count for number of users of subclass code
561 gpSharedMem
->refCount
= 0;
562 //dbg("DLL: dec'd refCount to %d, posting msg %x to app window %p", gpSharedMem->refCount,
563 // gpSharedMem->iCloseMsg, gpSharedMem->hwListener);
565 // Notify application that another O&S dialog has closed
566 PostMessage( gpSharedMem
->hwListener
, gpSharedMem
->iCloseMsg
, 0,0);
567 // Release any hold on the shared memory.
570 // Remove subclassing
571 WNDPROC wpOrig
= pow
->wpOrig
;
573 // Call original WM_DESTROY
574 return CallWindowProc(wpOrig
, hwnd
, msg
, wp
, lp
);
578 return CallWindowProc(pow
->wpOrig
, hwnd
, msg
, wp
, lp
);
582 // Subclass the listview control -- TODO: I think this is un-needed
583 LRESULT CALLBACK WINAPI
wpSubShellCtl(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
585 POWSubClassData pow
= (POWSubClassData
)GetProp(hwnd
, OW_PROP_NAME
);
587 return DefWindowProc(hwnd
, msg
, wp
, lp
);
593 HANDLE hDrop
= (HANDLE
)wp
;
594 int nFiles
= DragQueryFile(hDrop
, (UINT
)-1, NULL
, 0);
595 ////dbg("%d files dropped, fwding mesg to %p", nFiles, pow->lpData);
596 return SendMessage((HWND
)pow
->lpData
, msg
, wp
, lp
);
601 WNDPROC wpOrig
= pow
->wpOrig
;
603 //dbg("SHell view being destroyed");
604 return CallWindowProc(wpOrig
, hwnd
, msg
, wp
, lp
);
608 return CallWindowProc(pow
->wpOrig
, hwnd
, msg
, wp
, lp
);
609 } // END wpSubShellCtl
612 /* Check whether this application has been excluded, ie, whether we should not
613 * mess with its O&S dialogs
615 static BOOL
isExcluded(const char *szApp
)
618 HKEY hk
= regOpenKey(HKEY_CURRENT_USER
, OW_REGKEY_EXCLUDES_NAME
);
621 regGetDWORD(hk
, szApp
, &bEx
);
629 * Investigate the WM_CREATEPARAMS message
631 static void dbgCreateParams(LPVOID lpCreateParams
)
633 UNALIGNED
short * pcbData
= (UNALIGNED
short *)lpCreateParams
;
636 short cbData
= * pcbData
;
637 UNALIGNED byte
*pbData
= (UNALIGNED byte
*)pcbData
;
638 pbData
+= sizeof(short);
639 dbg("**CreateParams:");
640 dbg(" %d bytes of data, starting at x%p", cbData
, pbData
);
643 dbg(" First 8 bytes follow:");
644 int len
= min( cbData
, 8 );
647 for(i
=0; i
< len
; i
++)
652 dbg(" \"%s\" (hex follows)", s
);
655 for(i
=0; i
< len
; i
++)
657 sprintf(st
, "%02x ", pbData
[i
]);
664 dbg("CreateParams is NULL (%p)", pcbData
);
669 * This is the main hook callback, which watches window creation, and
670 * subclasses those which appear (with luck, correctly) to be O&S dialogs */
671 static LRESULT CALLBACK
CBTProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
677 return CallNextHookEx(ghMsgHook
, nCode
, wParam
, lParam
);
684 static char buf
[256];
685 HWND hwNew
= (HWND
)wParam
;
686 CBT_CREATEWND
* pcw
= (CBT_CREATEWND
*)lParam
;
687 CREATESTRUCT
* pcs
= (CREATESTRUCT
*) pcw
->lpcs
;
689 if( GetClassName(hwNew
, buf
, 255) && pcs
->lpszName
)
691 DWORD style
= (DWORD
)GetWindowLong(hwNew
, GWL_STYLE
);
692 DWORD exStyle
= (DWORD
)GetWindowLong(hwNew
, GWL_EXSTYLE
);
694 if( style
== OW_MATCH_STYLE
&& exStyle
== OW_MATCH_EXSTYLE
695 && strcmp(buf
, "#32770") == 0
696 && strcmp(pcs
->lpszName
, "Open") == 0 )
698 BOOL bTakeOver
= TRUE
;
700 //// FIND name of Calling app ////
701 char *szApp
= malloc( MAX_PATH
+1 );
702 if( szApp
&& GetModuleFileName(NULL
, szApp
, MAX_PATH
) )
704 if( isExcluded(szApp
) )
706 //dbg("DLL: Module: %s", szApp);
710 ///dbg("DLL: Found O&S dlg %p, attempting access to shared mem", hwNew);
712 if( bTakeOver
&& openSharedMem() )
714 //dbgCreateParams(pcs->lpCreateParams);
715 //dbg("DLL: Opened shared memory");
716 if( gpSharedMem
->bDisable
)
719 gpSharedMem
->refCount
++;
720 //dbg("DLL: Inc'd refCount to %d", gpSharedMem->refCount);
722 //dbg("DLL: Closed shared memory");
726 pcs
->style
&= ~WS_VISIBLE
;
727 ShowWindow(hwNew
, SW_HIDE
);
728 subclass(hwNew
, wpSubMain
, 0);
735 // Call the next hook, if there is one
736 return CallNextHookEx(ghMsgHook
, nCode
, wParam
, lParam
);
740 * Access to shared memory, and copy data to cache
742 int openSharedMem(void)
744 if( ghMap
!= NULL
|| gpSharedMem
!= NULL
)
750 ghMap
= OpenFileMapping(FILE_MAP_WRITE
, FALSE
, OW_SHARED_FILE_MAPPING
);
753 gpSharedMem
= (POWSharedData
)MapViewOfFile(ghMap
, FILE_MAP_WRITE
, 0,0, 0);
756 CopyMemory(&gOwShared
, gpSharedMem
, sizeof(OWSharedData
));
763 } // END openSharedMem
766 * Release any access to shared memory we may hold.
768 void closeSharedMem(void)
772 UnmapViewOfFile(gpSharedMem
);
781 } // END closeSharedMem
785 * Simply refreshes our cache of the shared data.
786 * Use this as a preference to the open/close-SharedMem functions.
788 * @returns 1 if successful, 0 on error.
790 int getSharedData(void)
793 if( openSharedMem() )
803 * exported function to setup the CBT hook, which watches window creation.
805 int DLLEXPORT
setHook(void)
807 if(ghMsgHook
!= NULL
)
809 //SendMessage(gOwShared.hwLog, LB_ADDSTRING, 0, (LPARAM)"Already hooked");
814 // SendMessage(hwLB, LB_ADDSTRING, 0, (LPARAM)"Failed to get shared data!!!");
815 // dbg("Hook failed to get shared mems");
818 //SendMessage(gOwShared.hwLog, LB_ADDSTRING, 0, (LPARAM)"Setting hook....");
819 ghMsgHook
= SetWindowsHookEx(WH_CBT
, CBTProc
, ghInst
, 0);
820 if(ghMsgHook
!= NULL
)
822 //dbg("Hooked okay");
823 //SendMessage(gOwShared.hwLog, LB_ADDSTRING, 0, (LPARAM)"Hooked ok!");
826 //dbg("Hook failed");
827 //SendMessage(gOwShared.hwLog, LB_ADDSTRING, 0, (LPARAM)"Failed hook");
833 * Exported function to remove the CBT hook.
835 int DLLEXPORT
rmvHook(void)
842 UnhookWindowsHookEx(ghSysMsgHook
);
845 //dbg("DLL: Removing hook");
848 UnhookWindowsHookEx(ghMsgHook
);
851 //dbg("DLL: removed hook okay");
858 // This callback handles SYSMSG hooks, which I have used to investigate the O&S dialog behaviour.
860 static LRESULT CALLBACK SysMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
865 return CallNextHookEx(ghMsgHook, nCode, wParam, lParam);
867 LPMSG pMsg = (MSG *)lParam;
868 if( pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST )
870 dbg("SysMsgProc: %d is code, pMsg: hwnd: %p, message: %d, wp: %x, lp: %x", nCode, pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
872 if( GetAsyncKeyState(VK_SHIFT) & 0x8000 )
874 LRESULT lRet = CallNextHookEx(ghSysMsgHook, nCode, wParam, lParam);
875 UnhookWindowsHookEx(ghSysMsgHook);
879 switch(pMsg->message)
883 dbg("WM_MENUSELECT: %p %d", pMsg->hwnd, LOWORD(pMsg->wParam));
885 HMENU hm = (HMENU)pMsg->lParam;
889 MENUITEMINFO mii ={0};
890 int nItems = GetMenuItemCount(hm);
891 dbg(" %d items in menu", nItems);
892 for(int i=0; i < nItems; i++)
894 mii.cbSize = sizeof(mii);
895 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING;
897 mii.dwTypeData = (LPTSTR)buf;
898 GetMenuItemInfo(hm, i, TRUE, &mii);
899 dbg(" Item %d: %.8s, %d", i, buf, mii.wID);
903 UnhookWindowsHookEx(ghSysMsgHook);
910 // Call the next hook, if there is one
911 return CallNextHookEx(ghSysMsgHook, nCode, wParam, lParam);
918 * Main DLL entry point
920 BOOL DLLEXPORT WINAPI
DLLPROC(HINSTANCE hDLLInst
, DWORD fdwReason
, LPVOID lpvReserved
)
924 case DLL_PROCESS_ATTACH
:
927 case DLL_PROCESS_DETACH
: