W
Mit dem MouseHook funktionierts
Da mir die Hilfe aus dem Forum etwas Wert ist hier meine Lösung:
Zuerst die MultiDisplay Klasse, ich weiss nicht mehr woher ich die habe eventuell mit den Angaben im MSDN selber zusammengebastelt.
MultiDisplay.h
#pragma once
#ifndef MC_MULTIDISPLAY_H
#define MC_MULTIDISPLAY_H
//----------------------------------------------------------------------------------
// Lokale Deklarationen
//----------------------------------------------------------------------------------
struct SMonInfo
{
CSize mMonitorSize;
CRect mMonitorRect;
};
typedef std::map<int, SMonInfo> DisplayInfo;
//------------------|---------------------------------------------------------------
// CMultiDisplay Deklaration der Multi Display Klasse
//----------------------------------------------------------------------------------
class CMultiDisplay
{
public:
CMultiDisplay ();
UINT DisplayCount () const;
CRect DisplayRect (int displayID);
CSize DisplaySize (int displayID);
private:
DisplayInfo mDisplays;
};
#endif // MC_MULTIDISPLAY_H
MultiDisplay.cpp
//----------------------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------------------
#include "StdAfx.h"
//----------------------------------------------------------------------------------
// MC++ Includes
//----------------------------------------------------------------------------------
#include "UI/_MultiDisplay.h"
//----------------------------------------------------------------------------------
// Debug Defines
//----------------------------------------------------------------------------------
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//----------------------------------------------------------------------------------
// Using Deklarationen
//----------------------------------------------------------------------------------
using namespace std;
//----------------------------------------------------------------------------------
// Lokale Deklarationen
//----------------------------------------------------------------------------------
struct ENUM_DISP_ARG
{
int mMonID;
DisplayInfo mInfo;
};
BOOL CALLBACK EnumDisplays (HMONITOR /*hMon*/, HDC /*dcMon*/, RECT* rect, LPARAM lParam)
{
ENUM_DISP_ARG* arg = reinterpret_cast<ENUM_DISP_ARG*>(lParam);
SMonInfo monInfo;
monInfo.mMonitorSize = CSize (rect->right - rect->left, rect->bottom - rect->top);
monInfo.mMonitorRect = CRect (rect->left, rect->top, rect->right, rect->bottom);
arg->mInfo[arg->mMonID] = monInfo;
arg->mMonID++;
return TRUE;
}
//==================|===============================================================
// CMultiDisplay Definition der Multi Display Klasse
//==================================================================================
//----- constructor / destructor ---------------------------------------------------
CMultiDisplay::CMultiDisplay ()
{
ENUM_DISP_ARG arg = { 0 };
arg.mMonID = 1;
EnumDisplayMonitors (0, 0, EnumDisplays, reinterpret_cast<LPARAM>(&arg));
mDisplays = arg.mInfo;
}
//----- DisplayCount ---------------------------------------------------------------
UINT CMultiDisplay::DisplayCount () const
{
return mDisplays.size ();
}
//----- DisplayRect ----------------------------------------------------------------
CRect CMultiDisplay::DisplayRect (int displayID)
{
DisplayInfo::const_iterator it = mDisplays.find (displayID);
if (it != mDisplays.end ())
return it->second.mMonitorRect;
return CRect (0, 0, 0, 0);
}
//----- DisplaySize ----------------------------------------------------------------
CSize CMultiDisplay::DisplaySize (int displayID)
{
DisplayInfo::const_iterator it = mDisplays.find (displayID);
if (it != mDisplays.end ())
return it->second.mMonitorSize;
return CSize (0, 0);
}
Dann die Applikationsklasse, hier befindet sich die MouseHook Funktion sowie das ein- und ausschalten des Hooks. Ich war ein wenig überrascht, dass ein aufrufen der SetCursorPos in der Hook Funktion wirkungslos war. Die Meldung mit PostMessage an den MainFrame aber funktioniert.
MX-FinalTuner.h
#pragma once
#ifndef MC_MX_FINALTUNER_H
#define MC_MX_FINALTUNER_H
//----------------------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------------------
#ifndef __AFXWIN_H__
#error "\"stdafx.h\" vor dieser Datei für PCH einschließen"
#endif
#include "resource.h" // Hauptsymbole
//------------------|---------------------------------------------------------------
// CMX_FinalTuner Deklaration der Applikation
//----------------------------------------------------------------------------------
class CMX_FinalTuner : public CWinAppEx
{
public:
CMX_FinalTuner();
MC::VApplication* Machine () const { return mMachine; }
private:
virtual BOOL InitInstance ();
virtual BOOL OnIdle (LONG lCount);
virtual int ExitInstance ();
afx_msg void OnAppAbout ();
DECLARE_MESSAGE_MAP()
MC::VApplication* mMachine;
HANDLE mThisApp;
MC::TPrinterControl* mPrtCtrl;
CMultiDisplay mMultiDisplay;
HHOOK mMouseHook;
};
extern CMX_FinalTuner gTheApp;
#endif // MC_MX_FINALTUNER_H
MX-FinalTuner.cpp
//----------------------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------------------
#include "StdAfx.h"
#include "MX_FinalTuner.h"
#include "MainFrm.h"
#include "AboutDlg.h"
#include "MX_FinalTunerDoc.h"
#include "SetupView.h"
#include "io.h"
#include "fcntl.h"
//----------------------------------------------------------------------------------
// Debug Defines
//----------------------------------------------------------------------------------
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//----------------------------------------------------------------------------------
// Using Deklarationen
//----------------------------------------------------------------------------------
using namespace MC;
using namespace std;
//----------------------------------------------------------------------------------
// Lokale Deklarationen
//----------------------------------------------------------------------------------
DECLARE_USER_MESSAGE(UWM_RESTORE_CURSOR)
BEGIN_MESSAGE_MAP(CMX_FinalTuner, CWinAppEx)
ON_COMMAND(ID_APP_ABOUT, &CMX_FinalTuner::OnAppAbout)
// Dateibasierte Standarddokumentbefehle
ON_COMMAND(ID_FILE_NEW, &CWinAppEx::OnFileNew)
ON_COMMAND(ID_FILE_OPEN, &CWinAppEx::OnFileOpen)
// Standarddruckbefehl "Seite einrichten"
ON_COMMAND(ID_FILE_PRINT_SETUP, &CWinApp::OnFilePrintSetup)
END_MESSAGE_MAP()
CMX_FinalTuner gTheApp;
// Diese beiden Variablen gefallen mir nicht besonders
// Habe aber keine andere Möglichkeit gefunden
CRect gMainDisplayRect;
CPoint gOldMousePos;
//----- MouseHookProc --------------------------------------------------------------
LRESULT CALLBACK MouseHookProc (int code, WPARAM wParam, LPARAM lParam)
{
PMSLLHOOKSTRUCT p = reinterpret_cast<PMSLLHOOKSTRUCT> (lParam);
CPoint mousePos = p->pt;
if (gMainDisplayRect.PtInRect (mousePos))
gOldMousePos = mousePos;
else
{
CFrameWnd* mainFrame = static_cast<CFrameWnd*> (AfxGetMainWnd ());
mainFrame->PostMessage (UWM_RESTORE_CURSOR, gOldMousePos.x, gOldMousePos.y);
}
return CallNextHookEx (NULL, code, wParam, lParam);;
}
Den cast auf CFrameWnd* kann man sich wahrscheinlich sparen.
CMX_FinalTuner.cpp
//==================|===============================================================
// CMX_FinalTuner Definition der Applikation
//==================================================================================
//----- constructor / destructor ---------------------------------------------------
CMX_FinalTuner::CMX_FinalTuner()
{
InitExeptions ();
SetThreadName (_T("UI_Thread"));
}
//----- InitInstance ---------------------------------------------------------------
BOOL CMX_FinalTuner::InitInstance()
{
// Diese Applikation darf nur einmal gestartet werden!
mThisApp = CreateMutexW (NULL, TRUE, _T("MX_FinalTuner"));
if (GetLastError () == ERROR_ALREADY_EXISTS)
{
ENSURE (mThisApp != NULL);
CloseHandle (mThisApp);
mThisApp = NULL;
return FALSE;
}
SetRegistryKey(_T("Micro Crystal"));
mMachine = CreateMachine ();
if (mMachine == NULL)
{
AfxMessageBox (_T("Could not create machine!"));
return FALSE;
}
if (ErrorFlag ())
{
UserError (IDS_INIT_ERROR, _T("CMX_FinalTuner::InitInstance"), eErrFatal);
ShowError (IDS_INIT_ERROR);
return FALSE;
}
mPrtCtrl = Object<TPrinterControl> (kPrinterControl);
ASSERT (mPrtCtrl != NULL);
mPrtCtrl->SetHandles (m_hDevMode, m_hDevNames);
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
AfxEnableControlContainer();
LoadStdProfileSettings(4);
mPrtCtrl->RestorePrinterSelection ();
CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CMX_FinalTunerDoc),
RUNTIME_CLASS(CMainFrame),
RUNTIME_CLASS(CSetupView));
if (!pDocTemplate)
return FALSE;
AddDocTemplate(pDocTemplate);
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
if (!ProcessShellCommand(cmdInfo))
return FALSE;
ObjRef<TParaHandler> (kParaHandler).SetMRUPointer (m_pRecentFileList);
InitShellManager ();
mMachine->PostUICreate ();
m_pMainWnd->ShowWindow (SW_SHOW);
m_pMainWnd->UpdateWindow ();
gMainDisplayRect = mMultiDisplay.DisplayRect (1);
gMainDisplayRect.DeflateRect (5,5);
mMouseHook = SetWindowsHookEx (WH_MOUSE_LL, MouseHookProc, NULL, NULL);
return TRUE;
}
//----- ExitInstance ---------------------------------------------------------------
int CMX_FinalTuner::ExitInstance()
{
if (mPrtCtrl != NULL)
mPrtCtrl->SavePrinterSelection ();
if (mMachine != NULL)
mMachine->Shutdown ();
UnhookWindowsHookEx (mMouseHook);
int res = CWinApp::ExitInstance();
return res;
}
In MainFrame ist nur die Funktion OnRestoreCursor interessant. Diese setzt den Cursor auf die letzte Position vor dem verlassen des Monitor1 Rect.
MainFrame.h
#pragma once
#ifndef MC_MX_FINALTUNER_MAINFRAME_H
#define MC_MX_FINALTUNER_MAINFRAME_H
//----------------------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------------------
#include "MX_FinalTunerView.h"
//----------------------------------------------------------------------------------
// Lokale Deklarationen
//----------------------------------------------------------------------------------
class CHardwareDlg;
//------------------|---------------------------------------------------------------
// CMainFrame Deklaration des MainFrame
//----------------------------------------------------------------------------------
class CMainFrame : public CFrameWnd
{
public:
virtual ~CMainFrame ();
protected:
CMainFrame ();
DECLARE_DYNCREATE (CMainFrame)
afx_msg LRESULT OnRestoreCursor (WPARAM, LPARAM);
DECLARE_MESSAGE_MAP()
};
#endif // MC_MX_FINALTUNER_MAINFRAME_H
MainFrame.cpp
//----------------------------------------------------------------------------------
// Includes
//----------------------------------------------------------------------------------
#include "StdAfx.h"
#include "MainFrm.h"
#include "resource.h"
//----------------------------------------------------------------------------------
// MC++ Includes
//----------------------------------------------------------------------------------
#include "MX_FinalTuner.h"
//----------------------------------------------------------------------------------
// Debug Defines
//----------------------------------------------------------------------------------
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//----------------------------------------------------------------------------------
// Using Deklarationen
//----------------------------------------------------------------------------------
using namespace std;
using namespace MC;
//----------------------------------------------------------------------------------
// Lokale Deklarationen
//----------------------------------------------------------------------------------
LPCTSTR kRegShowLiveImage = _T("Software\\Micro Crystal\\MX_FinalTuner\\LiveImage");
DECLARE_USER_MESSAGE(UWM_RESTORE_CURSOR)
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_REGISTERED_MESSAGE(UWM_RESTORE_CURSOR, OnRestoreCursor)
END_MESSAGE_MAP()
//==================|===============================================================
// CMainFrame Definition des MainFrame
//==================================================================================
//----- constructor / destructor ---------------------------------------------------
CMainFrame::CMainFrame()
: mActiveView (NULL),
mSetupView (NULL),
mAutomatView (NULL),
mHardwareStatus (NULL),
mProgressBox (NULL),
mKeyPad (NULL),
mMiniKeyboard (NULL),
mHardwareDlg (NULL)
{}
CMainFrame::~CMainFrame()
{}
//----- OnRestoreCursor ------------------------------------------------------------
LRESULT CMainFrame::OnRestoreCursor (WPARAM x, LPARAM y)
{
SetCursorPos (x, y);
SetFocus ();
return TRUE;
}
#endif //_DEBUG
Nochmals Danke an Martin. Hat spass gemacht das zu implementieren und gab ne ganze Menge Überstunden
Walter