Mausflackern
-
Hallo,
in meinem dialogfeldbasierenden Projekt überprüfe ich in der OnMouseMove()-Methode die aktuelle Position der Maus. Befindet sie sich in einem vordefinierten Rahmen, dann soll ein Rechteck gezeichnet werden.
Dies mache ich so:void MyDialog::OnMouseMove(UINT nFlags, CPoint point) { m_MouseHit = point; if ((point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom)) { HCURSOR hCursor; hCursor = AfxGetApp()->LoadCursor(IDC_HAND); SetCursor(hCursor); } InvalidateRgn(&diagrams,false); CDialog::OnMouseMove(nFlags, point); }
In der OnPaint() - Methode sieht es so aus:
void MyDialog::OnPaint() { ....... CPaintDC dc(this); //dc is an object of CPaintDC CDC memDC; CRect copyRect; CBitmap bmp, *pOldBmp; GetClientRect(©Rect); memDC.CreateCompatibleDC(&dc); bmp.CreateCompatibleBitmap(&dc,copyRect.Width(), copyRect.Height()); pOldBmp = memDC.SelectObject(&bmp); ..... //Zeichnen-Routine und Erstellen von Gdiplus-Objekten if (gdiSpeed.IsVisible(hit, &gdi)) // hittesting { Gdiplus::Pen rectangle(Gdiplus::Color(255,255,0,0),3); gdi.DrawRectangle(&rectangle,Rect.GetLeft()+1,Rect.GetTop()+1,397,297); } ...... }
Dabei ist die Region 'hit' identisch mit der Region 'diagrams'.
Mein Problem dabei ist, dass sobald ich
bmp.CreateCompatibleBitmap(&dc,copyRect.Width(), copyRect.Height());
benutze, mein Mauszeiger beim Bewegen der Maus flackert?!?
Benutze ich diese Zeile nicht, ist der Fensterhintergrund schwarz, ABER dafür läuft die Maus wie geschmiert (ganz smooth).
Und das verstehe ich wieder nicht. Für mein Verständnis ist es doch egal, ob ich ein "leeres" Bitmap oder ein "volles" Bitmap über mein DC blitte, die Funktion InvalidateRgn() wird doch bei beiden ausgeführt. Ausserdem soll er ja eigentlich den Hintergrund nicht neu zeichnen, habe ja auch 'false' übergeben.Falls was unklar ist, fragt ruhig. Wäre schon, wenn jemand sich diesem Problem annehmen könnte.
Gruss.
Paul.
-
Hallo!
Hab den Code jetzt nur so überflogen, aber meiner Meinung nach solltest du sowieso den Cursor nicht in OnMouseMove() neu laden, sondern die CREATESTRUCT modifizieren, in PreCreateWindow().
Kann aber sein, dass das auch nicht weiterhilft...
pw
-
Werde ich mal testen, aber ich dachte, dass PreCreateWindow() bei einer dialogfeldbasierten Anwendung nicht aufgerufen wird.
Und mir ist noch nicht klar, warum ich das dort machen soll, da ich den Mauszeiger nur ändern möchte, wenn ich in der bestimmten Region bin?
Aber es gibt ja so eine tolle Redewendung:
"Probieren(Programmieren) geht über studieren!"
-
Schau mal in die MSDN, da gibt es WM_SETCURSOR und noch mehrere Funktionen mit dem Namen "SetCursor".
Aber die Nachricht sollte schon das gesuchte sein, denke ich.
-
Irgendwie sehe ich nicht, was mir dies bringen soll. Eigentlich funktioniert mein Programm. Ich verwende die Doublebuffer-"Art" ,um das Flackern während des Zeichnens eines Diagramms zu vermeiden. Dafür erstellte ich ein Bitmap mit CreateCompatibleBitmap() und ein "SpeicherDC" mit CreateCompatibleDC(). Wenn ich das aber auf mein DC zurückblitte habe ich ja anstatt eines grauen Fensters ein schwarzes. CMatt hatte mir dann erklärt, dass es an dem Bitmap liegt, da es beim Erstellen leer ist und man zusätzlich erst das Original-DC hinein-blitten soll. Als ich das tat, hatte ich immer noch ein schwarzes Fenster, bis ich merkte, dass ich ja die Nachricht WM_ERASEBKND überschrieben hatte. Sie lieferte nur ein TRUE zurück. Habe ich das wieder auf default geändert, dann hatte ich zwar ein graues Fenster (Win 2000), jedoch trat das Flackern auf.
Also, es liegt definitiv an dem CreateCompatibleBitmap() und das hineinblitten.Ich hoffe, ihr versteht mich.
-
Hat denn noch niemand mit doublebuffering gearbeitet und dabei Mausflackern gehabt?
Habe sogar nochmal ein kleines Projekt geschrieben, in dem nur eine Linie gezeichnet wird. Das Fenster flackert nicht, aber der Mauszeiger schon.
-
dann lade das doch mal hoch für uns.
-
Webspace stelle ich dir (falls du keinen hast), mails einfach an estartu_de@c-plusplus.net aber vergiß bitte nicht, vorher den Debugordner aufzuräumen.
-
Habe leider kein Webspace, daher nehme ich jetzt das kleinere Projekt. Müsste auch gehen. Den ID_TIMER habe ich anhand des ResourceView-Fenster auf 101 gelegt:
// MyDoublebuffer.cpp : Defines the class behaviors for the application. // #include "stdafx.h" #include "MyDoublebuffer.h" #include "MyDoublebufferDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CMyDoublebufferApp BEGIN_MESSAGE_MAP(CMyDoublebufferApp, CWinApp) ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() // CMyDoublebufferApp construction CMyDoublebufferApp::CMyDoublebufferApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } // The one and only CMyDoublebufferApp object CMyDoublebufferApp theApp; // CMyDoublebufferApp initialization BOOL CMyDoublebufferApp::InitInstance() { // InitCommonControls() is required on Windows XP if an application // manifest specifies use of ComCtl32.dll version 6 or later to enable // visual styles. Otherwise, any window creation will fail. InitCommonControls(); CWinApp::InitInstance(); AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need // Change the registry key under which our settings are stored // TODO: You should modify this string to be something appropriate // such as the name of your company or organization SetRegistryKey(_T("Local AppWizard-Generated Applications")); CMyDoublebufferDlg dlg; m_pMainWnd = &dlg; INT_PTR nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; }
// MyDoublebufferDlg.cpp : implementation file // #include "stdafx.h" #include "MyDoublebuffer.h" #include "MyDoublebufferDlg.h" #include ".\mydoublebufferdlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CMyDoublebufferDlg dialog CMyDoublebufferDlg::CMyDoublebufferDlg(CWnd* pParent /*=NULL*/) : CDialog(CMyDoublebufferDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); counter = 0; } void CMyDoublebufferDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CMyDoublebufferDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_WM_TIMER() ON_WM_ERASEBKGND() END_MESSAGE_MAP() // CMyDoublebufferDlg message handlers BOOL CMyDoublebufferDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here SetTimer(ID_TIMER,100,NULL); return TRUE; // return TRUE unless you set the focus to a control } void CMyDoublebufferDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CMyDoublebufferDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDC* pDC = GetDC(); CDC memDC; CBitmap memBm, *pOldBm; CRect r; CPen pen(PS_SOLID,1,COLORREF(0xffffff)); CPen* pOldPen; GetClientRect(&r); memBm.CreateCompatibleBitmap(pDC,r.Width(),r.Height()); memDC.CreateCompatibleDC(pDC); // memDC.BitBlt(0,0,r.Width(),r.Height(),pDC,0,0,SRCPAINT); pOldBm = memDC.SelectObject(&memBm); memDC.MoveTo(10,3); pOldPen = memDC.SelectObject(&pen); for(int i = 0;i<=counter;i++) { memDC.LineTo(10+counter,3+counter); } pDC->BitBlt(0,0,r.right,r.bottom,&memDC,0,0,SRCPAINT); memDC.SelectObject(pOldBm); memDC.SelectObject(pOldPen); memDC.DeleteDC(); CDialog::OnPaint(); } } // The system calls this function to obtain the cursor to display while the user drags // the minimized window. HCURSOR CMyDoublebufferDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon); } void CMyDoublebufferDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default counter++; Invalidate(false); CDialog::OnTimer(nIDEvent); } BOOL CMyDoublebufferDlg::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default return CDialog::OnEraseBkgnd(pDC); }
// stdafx.cpp : source file that includes just the standard includes // MyDoublebuffer.pch will be the pre-compiled header // stdafx.obj will contain the pre-compiled type information #include "stdafx.h"
// MyDoublebuffer.h : main header file for the PROJECT_NAME application // #pragma once #ifndef __AFXWIN_H__ #error include 'stdafx.h' before including this file for PCH #endif #include "resource.h" // main symbols // CMyDoublebufferApp: // See MyDoublebuffer.cpp for the implementation of this class // class CMyDoublebufferApp : public CWinApp { public: CMyDoublebufferApp(); // Overrides public: virtual BOOL InitInstance(); // Implementation DECLARE_MESSAGE_MAP() }; extern CMyDoublebufferApp theApp;
// MyDoublebufferDlg.h : header file // #pragma once // CMyDoublebufferDlg dialog class CMyDoublebufferDlg : public CDialog { // Construction public: CMyDoublebufferDlg(CWnd* pParent = NULL); // standard constructor int counter; // Dialog Data enum { IDD = IDD_MYDOUBLEBUFFER_DIALOG }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: HICON m_hIcon; // Generated message map functions virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() public: afx_msg void OnTimer(UINT nIDEvent); afx_msg BOOL OnEraseBkgnd(CDC* pDC); };
// stdafx.h : include file for standard system include files, // or project specific include files that are used frequently, // but are changed infrequently #pragma once #ifndef VC_EXTRALEAN #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #endif // Modify the following defines if you have to target a platform prior to the ones specified below. // Refer to MSDN for the latest info on corresponding values for different platforms. #ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. #define WINVER 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. #endif #ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. #define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. #endif #ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. #endif #ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. #define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. #endif #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit // turns off MFC's hiding of some common and often safely ignored warning messages #define _AFX_ALL_WARNINGS #include <afxwin.h> // MFC core and standard components #include <afxext.h> // MFC extensions #include <afxdisp.h> // MFC Automation classes #include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls #ifndef _AFX_NO_AFXCMN_SUPPORT #include <afxcmn.h> // MFC support for Windows Common Controls #endif // _AFX_NO_AFXCMN_SUPPORT
//{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. // Used by MyDoublebuffer.rc // #define IDM_ABOUTBOX 0x0010 #define IDD_ABOUTBOX 100 #define IDS_ABOUTBOX 101 #define ID_TIMER 101 #define IDD_MYDOUBLEBUFFER_DIALOG 102 #define IDR_MAINFRAME 128 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 129 #define _APS_NEXT_COMMAND_VALUE 32771 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 102 #endif #endif
-
@estartu_de: Ok, ich versuche es gleich bei dir hochzuladen, habe es erst gerade gelesen.
Danke.EDIT: So, habe ich nun losgeschickt.
-
Es ist auch schon da, aber mein blöder Server klemmt gerade.
[Edit]Adresse s.u.[/Edit]
Morgen früh, sorry - ich glaube der Server zieht endlich um.
-
Kein Problem.
Ich kann mich eh nicht oft genug wiederholen: DANKE!
-
Der Server ist immer noch nicht erreichbar und beim Einrichten der anderen Domains muss wohl ein Fehler aufgetreten sein, was man per FTP macht wirkt sich nicht auf die Seite aus, die man per http bekommt.
Supportanfrage ist gestellt und sobald irgendeine Domain Lebenszeichen zeigt gebe ich hier auch den Link bekannt.
Tut mir echt leid, so einen massiven Ausfall hatte ich ja noch nie.
Wer es haben möchte, ich schicks auch per Mail raus.
-
Kein Problem. Ich sitze da jetzt so lange dran, dass ich auch noch warten kann.
@ alle anderen: ihr habt's gehört, estartu_de schickt es auch per Mail raus.
-
hier uploaden http://www.rapidshare.de/
-
Cool, danke!
http://rapidshare.de/files/2674749/MyDoublebuffer.zip.htmlPaul? Mail mir mal, dann bekommst du den Löschlink, damit du das runterwerfen kannst, wenn es erledigt ist.
-
Ok, schau in dein Postfach.
@schlau: Danke auch dir!
Ihr seid super.MfG.
Paul.
-
Wow, wer hat die Breakpoints da reingehauen.
Bei mir flackert nichts.
-
*UPS* Sorry. Hab ich vergessen.
Wäre seltsam, wenn da nichts flackern würde?!?
Achte mal darauf, wenn die Linie gezeichnet wird und du deinen Mauszeiger im Fenster lässt. Dann müsste der flackern.
-
Leider flackert bei mir nichts.
Und wie siehtst bei estartu aus??
Ich hab Win XP, SP 2. Vielleicht liegts auch im Grafickkartentreiber?!