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.
30 #include "openwidedll.h"
31 #include "openwidedllres.h"
33 #include "owSharedUtil.h"
36 // DLL Instance handle
37 HINSTANCE ghInst
= NULL
;
39 // Handle to shared memory access locking mutex.
40 HANDLE ghMutex
= NULL
;
41 POWSharedData gpSharedMem
= NULL
; // pointer to shared mem
42 // Handle to filemapping for shared mem
44 // System hook handles
45 HHOOK ghMsgHook
= NULL
, ghSysMsgHook
= NULL
;
47 // This cache is refreshed -- TODO: When?
48 OWSharedData gOwShared
; // stores copy of shared mem for access to non-pointer datas without extended blocking
52 /* Add an icon to the toolbar within the O&S Dialogs
53 * @param hwTB -- toolbar handle
54 * @param hIcn -- icon handle
56 * @returns -1 on error, or the index of the new icon within the imagelist.
58 int addIcon2TB(HWND hwTB
, HICON hIcn
)
60 HIMAGELIST hImgList
= NULL
;
61 hImgList
= (HIMAGELIST
)SendMessage(hwTB
, TB_GETIMAGELIST
, 0, 0);
64 // int nImgs = ImageList_GetImageCount(hImgList);
65 int idxNew
= ImageList_AddIcon(hImgList
, hIcn
);
68 //dbg("%s, Error adding to imglist: %s", __func__, geterrmsg());
73 //dbg("%s, Image added at index %d", __func__, idxNew);
74 SendMessage(hwTB
, TB_SETIMAGELIST
, 0, (LPARAM
)hImgList
);
82 * Adds a new button to the toolbar : hwnd
84 * @param hwnd -- parent window of toolbar, ie. the O&S Dialog.
86 * @returns 1 -- TODO: this should return 0 on error, but doesn't appear to.
88 static int addTBButton(HWND hwnd
)
90 // Locate the toolbar handle.
91 HWND hwTB
= findChildWindow(hwnd
, CID_TOOLBAR
, TOOLBARCLASSNAME
);
93 // Create toolbar button structure
95 tb
.iBitmap
= VIEW_NETCONNECT
;
97 // Load the toolbar icon, and add it to the imagelist, retaining the index.
99 HICON hIcn
= (HICON
)LoadImage(ghInst
, MAKEINTRESOURCE(IDI_TBICON
), IMAGE_ICON
, 16, 16, 0);
102 idxNew
= addIcon2TB(hwTB
, hIcn
);
106 tb
.iBitmap
= idxNew
; // set button image index
107 tb
.idCommand
= OW_TBUTTON_CMDID
; // set command id -- @see openwidedll.h
108 // Set the button style flags
109 tb
.fsStyle
= BTNS_AUTOSIZE
| BTNS_BUTTON
| BTNS_SHOWTEXT
| BTNS_DROPDOWN
; // BTNS_WHOLEDROPDOWN;
110 // Set the button state flags
111 tb
.fsState
= TBSTATE_ENABLED
;
112 // And give it a tooltip ? TODO: Check this
113 tb
.iString
= (INT_PTR
)"OpenWide by Lingo";
115 SendMessage(hwTB
, TB_ADDBUTTONS
, 1, (LPARAM
) & tb
);
117 // Ensure that the toolbar window is large enough to show the new button.
119 int idxLast
= SendMessage(hwTB
, TB_BUTTONCOUNT
, 0, 0) - 1;
120 if (SendMessage(hwTB
, TB_GETITEMRECT
, idxLast
, (LPARAM
) & r
))
123 GetWindowRect(hwTB
, &rw
);
124 MapWindowPoints(hwTB
, NULL
, (LPPOINT
) & r
, 2);
125 SetWindowPos(hwTB
, NULL
, 0, 0, (r
.right
+ 8) - rw
.left
, rw
.bottom
- rw
.top
+ 1, SWP_NOMOVE
| SWP_NOZORDER
);
128 } // END of addTBButton(...)
131 * Show a drop-down menu from the toolbar button.
133 * @param hwnd -- O&S dialog
134 * @param hwTB -- toolbar handle
135 * @param uiItem -- id of toolbar item ? -- TODO: Check this.
137 static void dropMenu(HWND hwnd
, HWND hwTB
, UINT uiItem
)
140 // Get the screen coords rectangle of the button
141 SendMessage(hwTB
, TB_GETRECT
, uiItem
, (LPARAM
) & r
);
142 MapWindowPoints(hwTB
, NULL
, (LPPOINT
) & r
, 2);
144 // Set the area for the menu to avoid. ? :: TODO: see Platform SDK on TrackPopupMenuEx
145 TPMPARAMS tpm
= { 0 };
146 tpm
.cbSize
= sizeof(tpm
);
149 // Create the menu structure.
150 HMENU hm
= CreatePopupMenu();
151 AppendMenu(hm
, MF_STRING
, OW_EXPLORE_CMDID
, "&Locate current folder with Explorer...");
152 AppendMenu(hm
, MF_STRING
, OW_SHOWDESK_CMDID
, "Show &Desktop [for Gabriel]...");
153 AppendMenu(hm
, MF_SEPARATOR
| MF_DISABLED
, 0, NULL
);
154 AppendMenu(hm
, MF_STRING
, OW_ABOUT_CMDID
, "&About OpenWide...");
155 SetMenuDefaultItem(hm
, OW_SHOWDESK_CMDID
, FALSE
);
157 // * This section is todo with having Favourite directories, and is unfinished.
159 AppendMenu(hm, MF_STRING, OW_ADDFAV_CMDID, "Add &Favourite");
160 SetMenuDefaultItem(hm, OW_ADDFAV_CMDID, FALSE);
161 POWSharedData pow = lockSharedData();
164 dbg("%s, Locked shared data ok", __func__);
165 PFavLink pFav = pow->pFaves;
168 MENUITEMINFO mii = { 0 };
169 mii.cbSize = sizeof(mii);
170 AppendMenu(hm, MF_SEPARATOR | MF_DISABLED, 0, NULL);
171 for (int i = 0; i < pow->nFaves; i++)
173 pFav = getNthFave(pow, i);
176 static char szBuf[MAX_PATH + 8];
178 dbgLink("inserting...", pFav);
179 mii.fMask = MIIM_STRING | MIIM_DATA | MIIM_ID;
180 mii.fType = MFT_STRING;
181 wsprintf(szBuf, "%s\tCtrl+%d", pFav->szFav, (pFav->idCmd - OW_FAVOURITE_CMDID) + 1);
182 mii.dwTypeData = szBuf;
183 mii.dwItemData = pFav->idCmd;
184 mii.wID = pFav->idCmd;
186 int iRes = InsertMenuItem(hm, -1, TRUE, &mii);
188 dbg("%s, Failed inserting item: %s", __func__, geterrmsg());
189 //idx = AppendMenu(hm, MF_STRING, iCmd++, pFav->szFav);
192 unlockSharedData(pow);
195 // Display, track, then destroy the menu.
196 TrackPopupMenuEx(hm
, TPM_HORIZONTAL
| TPM_RIGHTALIGN
| TPM_LEFTBUTTON
| TPM_VERTICAL
, r
.right
, r
.bottom
, hwnd
, &tpm
);
198 } // END of dropMenu(...)
202 // add a new 'place' into the Places bar.
203 int addPlace(HWND hwnd, PFavLink plk)
205 HWND hwTB = GetDlgItem(hwnd, CID_PLACES);
208 tb.iBitmap = giPlacesIcon;
209 tb.idCommand = plk->idCmd;
210 tb.fsStyle = BTNS_BUTTON | BTNS_SHOWTEXT; // BTNS_WHOLEDROPDOWN;
211 tb.fsState = TBSTATE_ENABLED;
212 tb.iString = (INT_PTR)PathFindFileName(plk->szFav);
213 SendMessage(hwTB, TB_ADDBUTTONS, 1, (LPARAM) & tb);
218 // Add a new favourite dir, first retrieving the path from the current view of the O&S dialog.
220 int addFavourite(HWND hwnd)
222 //static char szBuf[2*MAX_PATH+1];
223 assert( IsWindow(hwnd));
225 char *szBuf = (char *)GlobalAlloc(GPTR, 2 * MAX_PATH + 1);
228 if( SendMessage(hwnd, CDM_GETFOLDERPATH, 2*MAX_PATH, (LPARAM)szBuf) > 0 )
230 if( !faveExists(szBuf) )
232 PFavLink plNew = newFav(szBuf);
234 addPlace(hwnd, plNew);
236 dbg("%s, failed to create new fave", __func__);
239 dbg("%s, Fave: '%s' exists already", __func__, szBuf);
248 * Given the handle to the O&S dialog, this does the magic to it, such as
249 * adding toolbar buttons, setting the focus and view mode, and adding items to
252 * @returns 1, TODO:: There should be error indication, perhaps!
254 int openWide(HWND hwnd
)
257 int w
= gOwShared
.szDim
.cx
;
258 int h
= gOwShared
.szDim
.cy
;
259 int x
= gOwShared
.ptOrg
.x
;
260 int y
= gOwShared
.ptOrg
.y
;
261 SetWindowPos(hwnd
, NULL
, x
, y
, w
, h
, SWP_NOZORDER
);
264 HWND hwDirCtl
= GetDlgItem(hwnd
, CID_DIRLISTPARENT
);
265 WORD vCmdID
= viewToCmdID(gOwShared
.iView
);
266 // set the view mode, by sending a fake command message.
267 SendMessage(hwDirCtl
, WM_COMMAND
, MAKEWPARAM(vCmdID
, 0), 0);
270 focusDlgItem(hwnd
, gOwShared
.iFocus
);
273 // debug hook, to find menu cmd IDs
274 dbg("Hooking SYSMSG...");
275 ghSysMsgHook
= SetWindowsHookEx(
279 0 //GetCurrentThreadId() // Only install for THIS thread!!!
281 dbg("Hooking returned %p", ghSysMsgHook
);
283 // Allow drag&drop onto window. Unfortunately this doesn't work for the
284 // directory list, as that is already set to accept drops, as a command to
285 // copy/move files. I would have to subclass this too, and that's rather
287 DragAcceptFiles(hwnd
, TRUE
);
289 // Insert item into the system menu (right-click on titlebar)
290 HMENU hm
= GetSystemMenu(hwnd
, FALSE
);
291 AppendMenu(hm
, MF_SEPARATOR
| MF_DISABLED
, 0, NULL
);
292 AppendMenu(hm
, MF_STRING
, OW_EXPLORE_CMDID
, "&Locate current folder with Explorer...");
293 AppendMenu(hm
, MF_STRING
, OW_ABOUT_CMDID
, "&About OpenWide...");
295 addTBButton(hwnd
); // add the toolbar button.
297 // Modify the dir-list view flags
298 HWND hwShellCtl = GetDlgItem(hwnd, CID_DIRLISTPARENT);
299 hwShellCtl = GetDlgItem(hwShellCtl, 1);
300 ListView_SetExtendedListViewStyleEx(hwShellCtl, OW_LISTVIEW_STYLE, OW_LISTVIEW_STYLE );
303 } // END openWide(...)
306 /* Load the desktop folder into the dir list */
307 void showDesktop(HWND hwnd
)
309 char * szDesk
= GlobalAlloc(GPTR
, MAX_PATH
+1);
310 if( szDesk
&& SHGetSpecialFolderPath(hwnd
, szDesk
, CSIDL_DESKTOPDIRECTORY
,FALSE
) )
312 char *szOld
= getDlgItemText(hwnd
, CID_FNAME
);
313 SetDlgItemText(hwnd
, CID_FNAME
, szDesk
);
314 SendDlgItemMessage(hwnd
, CID_FNAME
, EM_SETSEL
, -1, -1);
315 SendDlgItemMessage(hwnd
, CID_FNAME
, EM_REPLACESEL
, FALSE
, (LPARAM
)"\\");
316 SendMessage(hwnd
, WM_COMMAND
, MAKEWPARAM(IDOK
, BN_CLICKED
), (LPARAM
)GetDlgItem(hwnd
, IDOK
));
318 SetDlgItemText(hwnd
, CID_FNAME
, szOld
);
320 SetDlgItemText(hwnd
, CID_FNAME
, "");
328 * This is the callback for the subclassed O&S dialog window, and it handles
329 * all the extra functionality, passing along messages to the old callback
330 * function unless the behaviour is modified.
333 LRESULT CALLBACK WINAPI
wpSubMain(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
337 dbgWM(hwnd, msg, wp, lp);
340 // retrieve a ptr to the extra information associated with the window.
341 POWSubClassData pow
= (POWSubClassData
)GetProp(hwnd
, OW_PROP_NAME
);
343 return DefWindowProc(hwnd
, msg
, wp
, lp
); // something's broken, so just allow default window function.
345 static char buffer
[MAX_PATH
+1];
351 // dbg("DLL: INITDIALOG");
352 LRESULT lRes
= CallWindowProc(pow
->wpOrig
, hwnd
, msg
, wp
, lp
); // call the old callback
353 ShowWindow(hwnd
, SW_HIDE
); // hide the window, until it's been magick-ed by openWide(...)
359 if( wp
&& !pow
->bSet
) // catch the first SHOWWINDOW only,
366 case WM_COMMAND
: // handle custom toolbar button commands, etc.
369 case OW_ABOUT_CMDID
: // about
370 MessageBox(hwnd
, "OpenWide is written by Luke Hudson. (c)2005", "About OpenWide", MB_OK
);
372 // show desktop item, or click on button rather than
373 // dropdown (ie, defaults to show desktop menuitem)
374 case OW_TBUTTON_CMDID
:
375 case OW_SHOWDESK_CMDID
:
378 case OW_EXPLORE_CMDID
: // Explore current dir in new Explorer window
380 // Build a command line
381 char *szParm
= "/select,";
382 wsprintf(buffer
, szParm
);
383 int len
= strlen(szParm
);
384 LPARAM lpBuf
= (LPARAM
)buffer
+ (LPARAM
)len
;
385 //dbg("CDM_GET..PATH, cbSize=%d, buffer = %p", MAX_PATH-len, lpBuf);
386 len
= SendMessage(hwnd
, CDM_GETFOLDERPATH
, MAX_PATH
- len
, lpBuf
); //(LPARAM)(char *)((unsigned int)buffer + (unsigned int)len));
389 // execute the command line
390 ShellExecute(hwnd
, NULL
, "explorer.exe", buffer
, NULL
, SW_SHOWNORMAL
);
395 // Handling of favourites -- UNFININSHED
396 case OW_ADDFAV_CMDID:
400 if (LOWORD(wp) >= OW_FAVOURITE_CMDID)
402 getFavourite(hwnd, (int)LOWORD(wp));
405 } // switch : command ids
408 // Handle notifications from the toolbar
411 NMHDR
*phdr
= (NMHDR
*)lp
;
412 HWND hwTB
= findChildWindow(hwnd
, CID_TOOLBAR
, TOOLBARCLASSNAME
);
413 if (phdr
->hwndFrom
== hwTB
)
415 // dbg("Got notify %d from toolbar", phdr->code);
416 if (phdr
->code
== TBN_DROPDOWN
)
418 NMTOOLBAR
*ptb
= (NMTOOLBAR
*)lp
;
419 if (ptb
->iItem
== OW_TBUTTON_CMDID
)
421 dropMenu(hwnd
, hwTB
, ptb
->iItem
);
422 return TBDDRET_DEFAULT
;
429 // handle notifications from the dir listview control
430 case WM_PARENTNOTIFY
:
431 if( LOWORD(wp
) == WM_CREATE
)
434 GetClassName((HWND
)lp
, buf
, 32);
436 if( strcmp(buf
, "SHELLDLL_DefView") == 0 )
438 // dbg("Shell defview ctl created");
439 // subclass((HWND)lp, wpSubShellCtl, (LPARAM)hwnd);
440 HWND hwLV
= GetDlgItem((HWND
)lp
, 1);
443 if( GetWindowLong(hwLV
, GWL_STYLE
) & LVS_REPORT
) // if details view is in effect.
445 // update style flags
446 ListView_SetExtendedListViewStyleEx(hwLV
, OW_LISTVIEW_STYLE
, OW_LISTVIEW_STYLE
);
447 // Send Control+NumpadPlus to expand all the columns to fit contents
449 in
[0].type
= INPUT_KEYBOARD
;
450 in
[0].ki
.wVk
= VK_CONTROL
;
451 in
[1].type
= INPUT_KEYBOARD
;
452 in
[1].ki
.wVk
= VK_ADD
;
453 in
[2].type
= INPUT_KEYBOARD
;
454 in
[2].ki
.wVk
= VK_CONTROL
;
455 in
[2].ki
.dwFlags
= KEYEVENTF_KEYUP
;
456 in
[3].type
= INPUT_KEYBOARD
;
457 in
[3].ki
.wVk
= VK_ADD
;
458 in
[3].ki
.dwFlags
= KEYEVENTF_KEYUP
;
459 HWND hwOld
= SetFocus(hwLV
);
460 SendInput(4, in
, sizeof(INPUT
));
464 //SetTimer(hwnd, 251177, 1, NULL); // set a timer, for what? TODO:: Check this
468 /// Deprecated -- I think? TODO: Check
472 KillTimer(hwnd, 251177);
473 HWND hwDirCtl = GetDlgItem(hwnd, CID_DIRLISTPARENT);
474 if( getSharedData() )
476 if( gOwShared.iView == V_THUMBS || gOwShared.iView == V_TILES )
478 // dbg("posting cmd message to reset view?");
479 WORD vCmdID = viewToCmdID(gOwShared.iView);
480 PostMessage(hwDirCtl, WM_COMMAND, MAKEWPARAM(vCmdID, 0), 0);
486 case WM_SYSCOMMAND
: // Handle system menu commands
488 int cmdId
= wp
& 0xFFF0;
489 if( cmdId
== OW_ABOUT_CMDID
)
491 MessageBox(hwnd
, "OpenWide is written by Luke Hudson. (c)2005", "About OpenWide", MB_OK
);
494 else if( cmdId
== OW_EXPLORE_CMDID
)
496 char * szParm
= "/select,";
497 wsprintf(buffer
, szParm
);
498 int len
= strlen(szParm
);
499 len
= SendMessage(hwnd
, CDM_GETFOLDERPATH
, MAX_PATH
-len
, (LPARAM
)(buffer
+len
));
502 ShellExecute(hwnd
, NULL
, "explorer.exe", buffer
, NULL
, SW_SHOWNORMAL
);
507 /* case WM_NCPAINT: // handle painting of non-content area, ie. window titlebar and frame.
509 HDC hdc = GetWindowDC(hwnd);
512 hbrOld = SelectObject(hdc, GetStockObject(BLACK_BRUSH));
513 hpOld = SelectObject(hdc, GetStockObject(NULL_PEN));
515 GetWindowRect(hwnd, &r);
520 RoundRect(hdc, r.left, r.top, r.right, r.bottom, 16,16);
521 SelectObject(hdc, hbrOld);
522 SelectObject(hdc, hpOld);
523 ReleaseDC(hwnd, hdc);
526 case WM_DROPFILES
: // Handle files which are dragged&dropped onto window.
528 HANDLE hDrop
= (HANDLE
)wp
;
529 int nFiles
= DragQueryFile(hDrop
, (UINT
)-1, NULL
, 0);
532 if( DragQueryFile(hDrop
, 0, buffer
, MAX_PATH
) )
534 if( PathIsDirectory(buffer
) )
536 // Set the view to dropped directory path.
537 SetDlgItemText(hwnd
, CID_FNAME
, buffer
);
538 SendDlgItemMessage(hwnd
, CID_FNAME
, EM_SETSEL
, -1, -1);
539 SendDlgItemMessage(hwnd
, CID_FNAME
, EM_REPLACESEL
, FALSE
, (LPARAM
)"\\");
540 SendMessage(hwnd
, WM_COMMAND
, MAKEWPARAM(IDOK
, BN_CLICKED
), (LPARAM
)GetDlgItem(hwnd
, IDOK
));
541 SetDlgItemText(hwnd
, CID_FNAME
, "");
542 if( getSharedData() )
544 focusDlgItem(hwnd
, gOwShared
.iFocus
);
553 //dbg("DLL: DESTROY");
554 if( openSharedMem() )
556 //dbg("DLL: Opened shared memory");
557 if( --gpSharedMem
->refCount
< 0 ) // Update the count for number of users of subclass code
558 gpSharedMem
->refCount
= 0;
559 //dbg("DLL: dec'd refCount to %d, posting msg %x to app window %p", gpSharedMem->refCount,
560 // gpSharedMem->iCloseMsg, gpSharedMem->hwListener);
562 // Notify application that another O&S dialog has closed
563 PostMessage( gpSharedMem
->hwListener
, gpSharedMem
->iCloseMsg
, 0,0);
564 // Release any hold on the shared memory.
567 // Remove subclassing
568 WNDPROC wpOrig
= pow
->wpOrig
;
570 // Call original WM_DESTROY
571 return CallWindowProc(wpOrig
, hwnd
, msg
, wp
, lp
);
575 return CallWindowProc(pow
->wpOrig
, hwnd
, msg
, wp
, lp
);
579 // Subclass the listview control -- TODO: I think this is un-needed
580 LRESULT CALLBACK WINAPI
wpSubShellCtl(HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
582 POWSubClassData pow
= (POWSubClassData
)GetProp(hwnd
, OW_PROP_NAME
);
584 return DefWindowProc(hwnd
, msg
, wp
, lp
);
590 HANDLE hDrop
= (HANDLE
)wp
;
591 int nFiles
= DragQueryFile(hDrop
, (UINT
)-1, NULL
, 0);
592 ////dbg("%d files dropped, fwding mesg to %p", nFiles, pow->lpData);
593 return SendMessage((HWND
)pow
->lpData
, msg
, wp
, lp
);
598 WNDPROC wpOrig
= pow
->wpOrig
;
600 //dbg("SHell view being destroyed");
601 return CallWindowProc(wpOrig
, hwnd
, msg
, wp
, lp
);
605 return CallWindowProc(pow
->wpOrig
, hwnd
, msg
, wp
, lp
);
606 } // END wpSubShellCtl
609 /* Check whether this application has been excluded, ie, whether we should not
610 * mess with its O&S dialogs
612 static BOOL
isExcluded(const char *szApp
)
615 HKEY hk
= regOpenKey(HKEY_CURRENT_USER
, OW_REGKEY_EXCLUDES_NAME
);
618 regGetDWORD(hk
, szApp
, &bEx
);
626 * Investigate the WM_CREATEPARAMS message
628 static void dbgCreateParams(LPVOID lpCreateParams
)
630 UNALIGNED
short * pcbData
= (UNALIGNED
short *)lpCreateParams
;
633 short cbData
= * pcbData
;
634 UNALIGNED byte
*pbData
= (UNALIGNED byte
*)pcbData
;
635 pbData
+= sizeof(short);
636 dbg("**CreateParams:");
637 dbg(" %d bytes of data, starting at x%p", cbData
, pbData
);
640 dbg(" First 8 bytes follow:");
641 int len
= min( cbData
, 8 );
644 for(i
=0; i
< len
; i
++)
649 dbg(" \"%s\" (hex follows)", s
);
652 for(i
=0; i
< len
; i
++)
654 sprintf(st
, "%02x ", pbData
[i
]);
661 dbg("CreateParams is NULL (%p)", pcbData
);
666 * This is the main hook callback, which watches window creation, and
667 * subclasses those which appear (with luck, correctly) to be O&S dialogs */
668 static LRESULT CALLBACK
CBTProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
674 return CallNextHookEx(ghMsgHook
, nCode
, wParam
, lParam
);
681 static char buf
[256];
682 HWND hwNew
= (HWND
)wParam
;
683 CBT_CREATEWND
* pcw
= (CBT_CREATEWND
*)lParam
;
684 CREATESTRUCT
* pcs
= (CREATESTRUCT
*) pcw
->lpcs
;
686 if( GetClassName(hwNew
, buf
, 255) && pcs
->lpszName
)
688 DWORD style
= (DWORD
)GetWindowLong(hwNew
, GWL_STYLE
);
689 DWORD exStyle
= (DWORD
)GetWindowLong(hwNew
, GWL_EXSTYLE
);
691 if (strcmp(buf
, "#32770") != 0 || strcmp(pcs
->lpszName
, "Open") != 0)
696 if( (style
== OW_MATCH_STYLE
&& exStyle
== OW_MATCH_EXSTYLE
)
697 || (style
== OW_MATCH_STYLE_W7
&& exStyle
== OW_MATCH_EXSTYLE_W7
))
699 BOOL bTakeOver
= TRUE
;
701 //// FIND name of Calling app ////
702 char *szApp
= malloc( MAX_PATH
+1 );
703 if( szApp
&& GetModuleFileName(NULL
, szApp
, MAX_PATH
) )
705 if( isExcluded(szApp
) )
707 //dbg("DLL: Module: %s", szApp);
711 ///dbg("DLL: Found O&S dlg %p, attempting access to shared mem", hwNew);
713 if( bTakeOver
&& openSharedMem() )
715 //dbgCreateParams(pcs->lpCreateParams);
716 //dbg("DLL: Opened shared memory");
717 if( gpSharedMem
->bDisable
)
720 gpSharedMem
->refCount
++;
721 //dbg("DLL: Inc'd refCount to %d", gpSharedMem->refCount);
723 //dbg("DLL: Closed shared memory");
727 pcs
->style
&= ~WS_VISIBLE
;
728 ShowWindow(hwNew
, SW_HIDE
);
729 subclass(hwNew
, wpSubMain
, 0);
736 // Call the next hook, if there is one
737 return CallNextHookEx(ghMsgHook
, nCode
, wParam
, lParam
);
741 * Access to shared memory, and copy data to cache
743 int openSharedMem(void)
745 if( ghMap
!= NULL
|| gpSharedMem
!= NULL
)
751 ghMap
= OpenFileMapping(FILE_MAP_WRITE
, FALSE
, OW_SHARED_FILE_MAPPING
);
754 gpSharedMem
= (POWSharedData
)MapViewOfFile(ghMap
, FILE_MAP_WRITE
, 0,0, 0);
757 CopyMemory(&gOwShared
, gpSharedMem
, sizeof(OWSharedData
));
764 } // END openSharedMem
767 * Release any access to shared memory we may hold.
769 void closeSharedMem(void)
773 UnmapViewOfFile(gpSharedMem
);
782 } // END closeSharedMem
786 * Simply refreshes our cache of the shared data.
787 * Use this as a preference to the open/close-SharedMem functions.
789 * @returns 1 if successful, 0 on error.
791 int getSharedData(void)
794 if( openSharedMem() )
804 * exported function to setup the CBT hook, which watches window creation.
806 int DLLEXPORT
setHook(void)
808 if(ghMsgHook
!= NULL
)
810 //SendMessage(gOwShared.hwLog, LB_ADDSTRING, 0, (LPARAM)"Already hooked");
815 // SendMessage(hwLB, LB_ADDSTRING, 0, (LPARAM)"Failed to get shared data!!!");
816 // dbg("Hook failed to get shared mems");
819 //SendMessage(gOwShared.hwLog, LB_ADDSTRING, 0, (LPARAM)"Setting hook....");
820 ghMsgHook
= SetWindowsHookEx(WH_CBT
, CBTProc
, ghInst
, 0);
821 if(ghMsgHook
!= NULL
)
823 //dbg("Hooked okay");
824 //SendMessage(gOwShared.hwLog, LB_ADDSTRING, 0, (LPARAM)"Hooked ok!");
827 //dbg("Hook failed");
828 //SendMessage(gOwShared.hwLog, LB_ADDSTRING, 0, (LPARAM)"Failed hook");
834 * Exported function to remove the CBT hook.
836 int DLLEXPORT
rmvHook(void)
843 UnhookWindowsHookEx(ghSysMsgHook
);
846 //dbg("DLL: Removing hook");
849 UnhookWindowsHookEx(ghMsgHook
);
852 //dbg("DLL: removed hook okay");
859 // This callback handles SYSMSG hooks, which I have used to investigate the O&S dialog behaviour.
861 static LRESULT CALLBACK SysMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
866 return CallNextHookEx(ghMsgHook, nCode, wParam, lParam);
868 LPMSG pMsg = (MSG *)lParam;
869 if( GetAsyncKeyState(VK_SHIFT) & 0x8000 )
871 LRESULT lRet = CallNextHookEx(ghSysMsgHook, nCode, wParam, lParam);
872 UnhookWindowsHookEx(ghSysMsgHook);
876 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);
908 if (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST) {
909 dbg("SysMsgProc: %d is code, pMsg: hwnd: %p, message: %d, wp: %x, lp: %x", nCode, pMsg->hwnd, pMsg->message, pMsg->wParam, pMsg->lParam);
913 // Call the next hook, if there is one
914 return CallNextHookEx(ghSysMsgHook, nCode, wParam, lParam);
921 * Main DLL entry point
923 BOOL DLLEXPORT WINAPI
DLLPROC(HINSTANCE hDLLInst
, DWORD fdwReason
, LPVOID lpvReserved
)
927 case DLL_PROCESS_ATTACH
:
930 case DLL_PROCESS_DETACH
: