That's right as the DLL gets mapped into the process space of the app ... but that's ok from my point of view as AV is a DLL.
Here's how I set the hook:
if( m_bEnableMM )
{
m_hShellHook = SetWindowsHookEx( WH_SHELL, MMCallback, AfxGetInstanceHandle(), 0);
}
And in my dll's .DEF file I have:
; AlbumView2.def : Declares the module parameters.
LIBRARY "AlbumView2.DLL"
EXPORTS
DllCanUnloadNow @1 PRIVATE
DllGetClassObject @2 PRIVATE
DllRegisterServer @3 PRIVATE
DllUnregisterServer @4 PRIVATE
MMCallback
KeybCallback
SECTIONS
.SHARDATA Read Write Shared
Notice the .SHARDATA section ... that's used if you want to share data between processes. Whenever a track changes in MJ I update the following two hotkey strings:
#pragma data_seg(".SHARDATA")
char m_szHK1[ 8192 ] = { "" };
char m_szHK2[ 8192 ] = { "" };
#pragma data_seg()
According to the tokens the user has specified.
Then whenever the user issues a hotkey I can paste the contents to the clipboard, e.g.:
LRESULT CALLBACK KeybCallback( int nCode, WPARAM wParam, LPARAM lParam )
{
static bool bProcessed = false;
switch( nCode )
{
case HC_ACTION:
// Process the key
if( (wParam == VK_F11 || wParam == VK_F12) && (lParam & ALT) && (GetAsyncKeyState( VK_CONTROL ) & 0x80000000) )
{
if( !bProcessed )
{
HANDLE hMem;
LPCTSTR pszData;
PVOID pvMemory;
DWORD dwLength;
// Mark as being processed
bProcessed = true;
// Point to the data in question
pszData = (( wParam == VK_F11 ) ? m_szHK1:m_szHK2);
// Allocate a memory handle
if( hMem = GlobalAlloc( GMEM_MOVEABLE | GMEM_SHARE, dwLength = (strlen( pszData ) + 1) ) )
{
// Open it
if( pvMemory = GlobalLock( hMem ) )
{
// Copy in the string
CopyMemory( pvMemory, pszData, dwLength );
// Unlock the handle
GlobalUnlock( hMem );
// Send to the clipboard
if( OpenClipboard( NULL ) )
{
EmptyClipboard();
SetClipboardData( CF_TEXT, hMem );
CloseClipboard();
}
}
}
// Unlock the memory
GlobalUnlock( hMem );
}
else
{
bProcessed = false;
}
break;
}
break;
}
return( CallNextHookEx( m_hKeybHook, nCode, wParam, lParam ) );
}