|
|
|
date: Thu, 29 May 2008 19:22:11 +0200,
group: microsoft.public.win32.programmer.ui
back
Re: SHBrowseForFolder with initial UNC path and no context menu?
"Alex Blekhman" skrev i melding
news:%23FSgl%23hwIHA.516@TK2MSFTNGP04.phx.gbl...
> "Gaute" wrote:
>> I use SHBrowseForFolder() for selecting folders, but I don't want the
>> context menu because it makes it too easy for novice users to rename
>> folders etc.
>
> The correct way to solve it is to give a user appropriate access rights.
> So, if a user shouldn't be changing some of folders, then create read-only
> user. Crippling standard UI because you decided that someone is "novice"
> is rude. Personally, I would be disappointed if the program I use imposed
> its own limitations to perfectly valid standard UI.
>
> Now, if you really need this, then you should do following:
>
> 1. Provide a hook procedure for "Browse for folder" dialog.
> 2. On initialization event find the tree-view control that displays
> folders.
> 3. Subclass the tree-view control.
> 4. When user right-clicks on a tree-view item, then handle the click and
> do whatever you deem necessary.
>
> HTH
> Alex
Thanks, you gave me new ideas. I think this will work (subclassing instead
of hook):
long CALLBACK BFF_TreeView_SubclFunc( HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam ) {
if( uMsg==WM_INITMENUPOPUP ) {
Some code to remove menu
return 0;
}
return CallWindowProc( pfnOriBFFWndProc, hWnd, uMsg, wParam, lParam );
}
int CALLBACK BFFCallbackProc(HWND hWnd,UINT uMsg, LPARAM lp, LPARAM pData) {
if( uMsg==BFFM_INITIALIZED ) { some code to subclass SysTreeView32 }
return 0;
}
Best regards from Gaute
date: Fri, 30 May 2008 14:48:42 +0200
author: Gaute am
Re: SHBrowseForFolder with initial UNC path and no context menu?
This became my implementation - it is tested on XP and Vista:
static WNDPROC pfnOrigBFFTreeProc = NULL;
static long CALLBACK
BFFTreeSubclProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
if( uMsg == WM_INITMENUPOPUP ) {
CMenu *pMenu = CMenu::FromHandle( HMENU(wParam) );
lblRestart :
for( int i=0; i<pMenu->GetMenuItemCount(); i++ ) {
int id = pMenu->GetMenuItemID(i);
if( id!= 8 /* XP Expand*/ && id!=9 /* XP Collapse*/ &&
id!=19 /*Vista Expand*/ && id!=20 /*Vista Collapse*/)
if( pMenu->RemoveMenu( i, MF_BYPOSITION ) )
goto lblRestart;
}
return 0;
}
return CallWindowProc( pfnOrigBFFTreeProc, hWnd, uMsg, wParam, lParam );
}
int CALLBACK
BrowseCallbackProc(HWND hWnd,UINT uMsg, LPARAM lp, LPARAM pData)
{
TCHAR szDir[MAX_PATH];
switch(uMsg) {
case BFFM_INITIALIZED:
{ HWND hParent = hWnd;
HWND hCtl = FindWindowEx( hParent, NULL, _T("SHBRowseForFolder
ShellNameSpace Control"), NULL );
if( IsWindow(hCtl) ) hParent=hCtl;
hCtl = FindWindowEx( hParent, NULL, _T("SysTreeView32"), NULL );
ASSERT( hCtl );
if( IsWindow(hCtl) && pfnOrigBFFTreeProc != BFFTreeSubclProc ) {
pfnOrigBFFTreeProc = (WNDPROC) SetWindowLong( hCtl,
GWL_WNDPROC, (DWORD) BFFTreeSubclProc );
}
}
break;
}
return 0;
}
bool MyBrowseForFolder( HWND hParent, CString& sOutPath, LPCTSTR
pszInitialDir, LPCTSTR pszTitle )
{
bool bSelected = false;
LPMALLOC pMalloc;
if( SUCCEEDED(::SHGetMalloc(&pMalloc)) ) {
BROWSEINFO bi; ZeroMemory(&bi,sizeof(bi));
bi.hwndOwner = hParent;
bi.lpszTitle = pszTitle;
bi.ulFlags = BIF_RETURNFSANCESTORS |
BIF_RETURNONLYFSDIRS;
/*if( IsShellDllVersionAtLeast(5,0) )*/ {
bi.ulFlags |= BIF_NEWDIALOGSTYLE;
bi.ulFlags |= BIF_NONEWFOLDERBUTTON;
bi.ulFlags |= BIF_SHAREABLE;
}
bi.lpfn = BrowseCallbackProc;
bi.lParam = (LPARAM) pszInitialDir;
LPITEMIDLIST pidl = ::SHBrowseForFolder(&bi);
if( pidl ) {
TCHAR szDir[MAX_PATH+1];
if( ::SHGetPathFromIDList(pidl,szDir) ) {
sOutPath = szDir;
bSelected = true;
}
pMalloc->Free(pidl); // Free the PIDL allocated by
SHBrowseForFolder.
}
pMalloc->Release(); // Release the shell's allocator.
}
return bSelected;
}
date: Sat, 31 May 2008 09:49:16 +0200
author: Gaute am
Re: SHBrowseForFolder with initial UNC path and no context menu?
"Gaute" wrote:
> This became my implementation - it is tested on XP and Vista:
>
> [...]
>
> lblRestart :
> for( ... ) {
> if( ... )
> if( ... )
> goto lblRestart;
Beware of goto jumps across scopes. It may be OK with C but may
lead to all kind of quirks with C++, since compiler may generate a
code that should work when execution flow exits a scope.
> return CallWindowProc( pfnOrigBFFTreeProc, hWnd, uMsg, wParam,
> lParam );
I'd call `DefSubclassProc'. You may be not alone who sublcass the
control.
> int CALLBACK
> BrowseCallbackProc(HWND hWnd,UINT uMsg, LPARAM lp, LPARAM pData)
> {
> TCHAR szDir[MAX_PATH];
^^^^^
This variable is a) uninitialized and b) never used in the
function.
> pfnOrigBFFTreeProc = (WNDPROC) SetWindowLong( hCtl,
> GWL_WNDPROC, (DWORD) BFFTreeSubclProc );
If your target system is Windows XP and above, you'd better use
new subclassing routines available with XP's ComCtl32.dll instead
of `SetWindowLong'. Read here more about them:
"Subclassing Controls"
http://msdn2.microsoft.com/en-us/library/bb773183(VS.85).aspx
See "Subclassing Controls Using ComCtl32.dll version 6" section.
Also, don't forget to remove your subclass routine in the end.
HTH
Alex
date: Sat, 31 May 2008 11:16:30 +0300
author: Alex Blekhman
|
|