updating dialog static text is not working - mfc

mfc(Cdialog):
//CImgView.cpp:
void CImgView::OnMouseMove(UINT nFlags, CPoint pt)
{
CPoint ptImg = GetScrollPosition() + pt;
sprintf(sbuf,"X %d Y %d", ptImg.x, ptImg.y);
((CImgDlg*)GetParent())->Update1();
CScrollView::OnMouseMove(nFlags, pt);
}
//CImgDlg.cpp:
void CImgDlg::Update1()
{
SetDlgItemText(IDC_STATIC_xy, sbuf);
}
static text,IDC_STATIC_xy, does not get updated.

It seems unlikely that a dialog is the parent of CImgView, so GetParent is probably getting some other window. Try and provide a pointer to the CImgDlg object that can be saved in CImgView so it can call pImgDlg->Update1().

Related

Make CRectTracker object top-most

I have an MFC dialog application where the user can upload a photo and it will be displayed within the dialog. After they have uploaded an image they will be able select a region of this image and for this I am using the CRectTracker class. My problem however is that the tracker is currently being displayed behind the image.
What I have tried so far is:
Googling how to set the z-order of the CRectTracker object, but cannot seem to find any documentation on it.
Set the z-order of the image to the bottom using SetWindowPos(&wndBottom,...) but the tracker still appears behind the image.
I am using a Picture Control (type Bitmap) to display the image.
EDIT:
I draw the tracker in the OnPaint() method of my dialog class like this:
CPaintDC dc(this);
m_tracker.Draw(&dc);
which is being called by this->Invalidate(); in OnLButtonDown and OnMouseMove whenever I need to refresh the tracker:
void CTAB3::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_tackerFlag)
{
int nHitTest;
nHitTest = m_tracker.HitTest(point);
if (nHitTest < 0) // if the mouse down point is outside of the rect tracker
{
m_start = point; // Record the start drawing point
m_bDraw = TRUE; // set m_bDraw (in handle funtion WM_MOUSEMOVE will test this to decide whether to draw)
}
else // if the mouse down point is inside of the rect tracker
{
m_tracker.Track(this, point, FALSE); // start drag the rect tracker
this->Invalidate(); // make the window paint to refresh the track
}
}
CDialogEx::OnLButtonDown(nFlags, point);
}
void CTAB3::OnMouseMove(UINT nFlags, CPoint point)
{
// m_bDraw is set to true in funtion OnLButtonDown and set to false in funtion OnLButtonDown
// m_bDraw is use for testing if the mouse is moved along with the left button is pressed.
if (m_bDraw)
{
m_tracker.m_rect.SetRect(m_start, point); // set the rect of rect tracker
this->Invalidate(); // make the window paint to refresh the rect
}
CDialogEx::OnMouseMove(nFlags, point);
}
EDIT2:
Based on #ConstantineGeorgiou comment I decided to keep trying to implement the tracker with the resize handles using Track() as this would be the preferred solution for my project. I finally managed to draw the tracker on top of the image, but I am not particularly happy with the solution I ended up with. Basically I moved the Draw() function to the mouse move handler, so that the tracker is drawn after the OnPaint() has drawn everything else on the dialog. If anyone has any suggestion on better ways to do this, I would be very grateful for any feedback.
This is how I implemented it with the Draw() in the OnMouseMove() handler:
//In the header file:
BOOL m_bDraw = FALSE
void CTAB3::OnLButtonDown(UINT nFlags, CPoint point)
{
if (m_tackerFlag)
{
m_tracker.Track(this, point, FALSE); // start drag the rect tracker
this->Invalidate();
m_bDraw = TRUE;
}
CDialogEx::OnLButtonDown(nFlags, point);
}
void CTAB3::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bDraw)
{
//Draw tracker
CDC* dc = GetDC();
m_tracker.Draw(dc);
}
CDialogEx::OnMouseMove(nFlags, point);
}
BOOL CTAB3::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if (m_tackerFlag)
{
if (pWnd == this && m_tracker.SetCursor(this, nHitTest))
{
return TRUE;
}
}
return CDialogEx::OnSetCursor(pWnd, nHitTest, message);
}
void CTAB3::OnPaint()
{
CPaintDC dc(this); // device context for painting
//m_tracker.Draw(&dc);
}

How to move window by right mouse button using C++?

I need to move window by right mouse button. The window has no caption, titlebar. By left button it works
void CMyHud::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
SendMessage(WM_SYSCOMMAND, SC_MOVE|0x0002);
CDialogEx::OnLButtonDown(nFlags, point);
}
But if I place this code on OnRButtonDown it dosen't work. What is the problem?
Well, the solution is found, thanks to Mark Ransom:
CRect pos;
void CMyHud::OnRButtonDown(UINT nFlags, CPoint point)
{
pos.left = point.x;
pos.top = point.y;
::SetCapture(m_hWnd);
CDialogEx::OnRButtonDown(nFlags, point);
}
void CMyHud::OnMouseMove(UINT nFlags, CPoint point)
{
CWnd* pWnd = CWnd::FromHandle(m_hWnd);
CRect r;
if(GetCapture() == pWnd)
{
POINT pt;
GetCursorPos(&pt);
GetWindowRect(r);
pt.x -= pos.left;
pt.y -= pos.top;
MoveWindow(pt.x, pt.y, r.Width(), r.Height(),TRUE);
}
CDialogEx::OnMouseMove(nFlags, point);
}
void CMyHud::OnRButtonUp(UINT nFlags, CPoint point)
{
ReleaseCapture();
CDialogEx::OnRButtonUp(nFlags, point);
}
In your OnRButtonDown function, do a SetCapture to ensure all mouse messages are routed to your window while the mouse button is down. Also store the mouse position in a member variable. Now, in your OnMouseMove function, check to see if GetCapture returns an object with the same HWND as yours - if it does, calculate the difference between the current mouse position and the saved one, then call MoveWindow to move the window.
In regards to left-mouse click:
SC_MOVE|0x0002 comes out as 0xF012 or SC_DRAGMOVE. This is apparently an undocumented constant. There is probably a good reason Microsoft doesn't want anybody to use this, that's why they have hidden it.
Also WM_SYSCOMMAND is a notification message. You should respond to it, not send it. To drag the window with left-mouse click:
message map ...
ON_WM_NCHITTEST()
LRESULT CMyDialog::OnNcHitTest(CPoint p)
{
//responding to a notification message
return HTCAPTION;
}
To drag the window with right-mouse you have to override OnRButtonDown, OnMouseMove, OnRButtonUp and make your own routine. But Window's behaviour gets very confusing. Is that really worth it?
you can use mouse message to realize.
WM_RBUTTONDOWN, WM_MOUSEMOVE

Why is my CStatic derived class does not receive OnMouseLeave event but can receive OnMouseMove

The code
#include "stdafx.h"
#include "TestClass.h"
IMPLEMENT_DYNAMIC(TestClass, CStatic)
TestClass::TestClass()
{
}
void TestClass::Ini(CWnd* parent)
{
Create(L"hello world",WS_CHILD|WS_VISIBLE|SS_CENTER | SS_NOTIFY ,
CRect(0,0,50,50), parent, 200);
}
void TestClass::OnMouseMove(UINT nFlags, CPoint point)
{
CStatic::OnMouseMove(nFlags, point);
}
void TestClass::OnMouseLeave()
{
CStatic::OnMouseLeave();
}
TestClass::~TestClass()
{
}
BEGIN_MESSAGE_MAP(TestClass, CStatic)
ON_WM_MOUSEMOVE()
ON_WM_MOUSELEAVE()
END_MESSAGE_MAP()
As you can see I'm using SS_NOTIFY and I can not get the OnMouseLeave event, but OnMouseMove working without any problems.
Note:
I creating a custom window so I removed the title bar.
If you want to handle the mouse leave and mouse hover event you have to call TrackMouseEvent in the OnMouseMove function.
void TestClass::OnMouseMove(UINT nFlags, CPoint point)
{
TRACKMOUSEEVENT MouseBehaviour;
CStatic::OnMouseMove(nFlags, point);
MouseBehaviour.cbSize = sizeof(TRACKMOUSEEVENT);
MouseBehaviour.dwFlags = TME_HOVER | TME_LEAVE;
MouseBehaviour.hwndTrack = GetSafeHwnd();
MouseBehaviour.dwHoverTime = HOVER_DEFAULT;
TrackMouseEvent(&MouseBehaviour);
}

Use button in a dialog to select shape in MFC

I am doing a small drawing tool with MFC.
I define five shapes: rectangle, line, circle, ellipse and dot. int m_drawType is used to switch between five shapes.
The code as below:
void CDrawToolView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_startRect=TRUE;
m_startPoint=point;
m_OldPoint=point;
::SetCursor(m_HCross);
CView::OnLButtonDown(nFlags, point);
}
void CDrawToolView::OnMouseMove(UINT nFlags, CPoint point)
{
CClientDC dc(this);
dc.SetROP2(R2_NOT);
dc.SetROP2(R2_NOT);
dc.SelectStockObject(NULL_BRUSH);
if(TRUE==m_startRect)
{
switch(m_drawType)
{
case 1://Rectangle
::SetCursor(m_HCross);
dc.Rectangle(CRect(m_startPoint,m_OldPoint));
dc.Rectangle(CRect(m_startPoint,point));
m_OldPoint=point;
break;
case 2: //Line
::SetCursor(m_HCross);
dc.MoveTo(m_startPoint);
dc.LineTo(m_OldPoint);
dc.MoveTo(m_startPoint);
dc.LineTo(point);
m_OldPoint=point;
break;
.
.
.
}
}
CView::OnMouseMove(nFlags, point);
}
void CDrawToolView::OnLButtonUp(UINT nFlags, CPoint point)
{
m_startRect=FALSE;
::ClipCursor(NULL);
CClientDC dc(this);
dc.SelectStockObject(NULL_BRUSH);
switch(m_drawType)
{
case 1: //Retangle
dc.Rectangle(CRect(m_startPoint,m_OldPoint));
dc.Rectangle(CRect(m_startPoint,point));
break;
case 2: //Line
dc.MoveTo(m_startPoint);
dc.LineTo(m_OldPoint);
dc.MoveTo(m_startPoint);
dc.LineTo(point);
break;
.
.
.
}
CView::OnLButtonUp(nFlags, point);
}
void CDrawToolView::OnEditShape() // when click menu-edit-shape a dialog is pop up
{
CShapeDlg dlg;
dlg.DoModal();
}
The pop up dialog as below:
I have created a dialog of five buttons. My problem is I don't know how to link between the buttons and these five shapes. Could some one help me?
So your question is how to make the buttons of CShapeDlg set m_drawType?
Your dialog could have a local public drawType variable. Introduce button click event handlers for the buttons.
BEGIN_MESSAGE_MAP(CShapeDlg, CDialog)
ON_BN_CLICKED(IDC_BUTTON1, &CShapeDlg::OnBnClickedButton1)
... etc.
ON_BN_CLICKED(IDC_BUTTON5, &CShapeDlg::OnBnClickedButton5)
END_MESSAGE_MAP()
Make the handlers set the local drawType variable to integer value 0 - 4 as the case may be.
void CShapeDlg::OnBnClickedButton1() { drawType = 0; }
... etc.
void CShapeDlg::OnBnClickedButton5() { drawType = 4; }
Then
if (dlg.DoModal() == IDOK)
m_drawType = dlg.drawType;
The dialog should have an m_drawtype variable that it sets when a button is clicked. When DoModal returns this variable can be read to get the result:
dlg.DoModal();
m_drawtype = dlg.m_drawtype;

C++ MFC MDI View rendering

in my application, i currently have 2 document types. The one i will be focusing on, will be the second. My application is a 3d engine editor, which is build in MFC MDI. The first document is the render window, which works perfect, because it's simple to extract the hwnd of it, and then send it to my graphics class. But my second window, which is scripting, is supposed (for now) just to have a rich edit. But for some reason, it doesn't render(actually it does, but only once :/).
CEditorScriptView.h
#pragma once
#include "CEditorDoc.h"
class CCEditorCntrItem;
class CCEditorScriptView : public CView
{
public: // create from serialization only
CCEditorScriptView();
DECLARE_DYNCREATE(CCEditorScriptView)
// Attributes
public:
CCEditorDoc* GetDocument() const;
static CCEditorScriptView * GetView();
// m_pSelection holds the selection to the current CCEditorCntrItem.
// For many applications, such a member variable isn't adequate to
// represent a selection, such as a multiple selection or a selection
// of objects that are not CCEditorCntrItem objects. This selection
// mechanism is provided just to help you get started
// TODO: replace this selection mechanism with one appropriate to your app
CCEditorCntrItem* m_pSelection;
CRichEditCtrl* m_rEdit;
int TYPE;
// Operations
public:
// Overrides
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual void OnInitialUpdate(); // called first time after construct
virtual BOOL IsSelected(const CObject* pDocItem) const;// Container support
// Implementation
public:
virtual ~CCEditorScriptView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
afx_msg void OnDestroy();
afx_msg void OnSetFocus(CWnd* pOldWnd);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnInsertObject();
afx_msg void OnCancelEditCntr();
afx_msg void OnFilePrint();
afx_msg void OnFilePrintPreview();
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in CEditorView.cpp
inline CCEditorDoc* CCEditorScriptView::GetDocument() const
{ return reinterpret_cast<CCEditorDoc*>(m_pDocument); }
#endif
CEditorScriptView.cpp:
#include "stdafx.h"
// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
// and search filter handlers and allows sharing of document code with that project.
#ifndef SHARED_HANDLERS
#include "CEditor.h"
#endif
#include "CEditorDoc.h"
#include "CntrItem.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CCEditorView
#pragma region CCEditorScriptView
IMPLEMENT_DYNCREATE(CCEditorScriptView, CView)
BEGIN_MESSAGE_MAP(CCEditorScriptView, CView)
ON_WM_DESTROY()
ON_WM_SETFOCUS()
ON_WM_SIZE()
ON_COMMAND(ID_OLE_INSERT_NEW, &CCEditorScriptView::OnInsertObject)
ON_COMMAND(ID_CANCEL_EDIT_CNTR, &CCEditorScriptView::OnCancelEditCntr)
ON_COMMAND(ID_FILE_PRINT, &CCEditorScriptView::OnFilePrint)
ON_WM_CONTEXTMENU()
ON_WM_RBUTTONUP()
END_MESSAGE_MAP()
// CCEditorView construction/destruction
CCEditorScriptView::CCEditorScriptView()
{
EnableActiveAccessibility();
m_pSelection = NULL;
// TODO: add construction code here
m_rEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER|ES_MULTILINE,
CRect(10,10,500,500), this, 1);
//m_rEdit->SetFocus();
TYPE = ID_CEDITOR_VIEW_SCRIPT;
}
CCEditorScriptView::~CCEditorScriptView()
{
}
BOOL CCEditorScriptView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
// CCEditorView drawing
void CCEditorScriptView::OnDraw(CDC* pDC)
{
if (!pDC)
return;
CCEditorDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
// TODO: also draw all OLE items in the document
// Draw the selection at an arbitrary position. This code should be
// removed once your real drawing code is implemented. This position
// corresponds exactly to the rectangle returned by CCEditorCntrItem,
// to give the effect of in-place editing.
// TODO: remove this code when final draw code is complete.
m_rEdit->UpdateWindow();
if (m_pSelection != NULL)
{
CSize size;
CRect rect(10, 10, 210, 210);
if (m_pSelection->GetExtent(&size, m_pSelection->m_nDrawAspect))
{
pDC->HIMETRICtoLP(&size);
rect.right = size.cx + 10;
rect.bottom = size.cy + 10;
}
m_pSelection->Draw(pDC, rect);
}
}
// MDI view implementation file
CCEditorScriptView * CCEditorScriptView::GetView()
{
CMDIChildWnd * pChild =
((CMDIFrameWnd*)(AfxGetApp()->m_pMainWnd))->MDIGetActive();
if ( !pChild )
return NULL;
CView * pView = pChild->GetActiveView();
if ( !pView )
return NULL;
// Fail if view is of wrong kind
/*if ( ! pView->IsKindOf( RUNTIME_CLASS(CCEditorRenderView) ) )
return NULL;*/
return (CCEditorScriptView *) pView;
}
void CCEditorScriptView::OnInitialUpdate()
{
CView::OnInitialUpdate();
// TODO: remove this code when final selection model code is written
m_pSelection = NULL; // initialize selection
}
void CCEditorScriptView::OnDestroy()
{
// Deactivate the item on destruction; this is important
// when a splitter view is being used
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL && pActiveItem->GetActiveView() == this)
{
pActiveItem->Deactivate();
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
CView::OnDestroy();
}
// OLE Client support and commands
BOOL CCEditorScriptView::IsSelected(const CObject* pDocItem) const
{
// The implementation below is adequate if your selection consists of
// only CCEditorCntrItem objects. To handle different selection
// mechanisms, the implementation here should be replaced
// TODO: implement this function that tests for a selected OLE client item
return pDocItem == m_pSelection;
}
void CCEditorScriptView::OnInsertObject()
{
// Invoke the standard Insert Object dialog box to obtain information
// for new CCEditorCntrItem object
COleInsertDialog dlg;
if (dlg.DoModal() != IDOK)
return;
BeginWaitCursor();
CCEditorCntrItem* pItem = NULL;
TRY
{
// Create new item connected to this document
CCEditorDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
pItem = new CCEditorCntrItem(pDoc);
ASSERT_VALID(pItem);
// Initialize the item from the dialog data
if (!dlg.CreateItem(pItem))
AfxThrowMemoryException(); // any exception will do
ASSERT_VALID(pItem);
if (dlg.GetSelectionType() == COleInsertDialog::createNewItem)
pItem->DoVerb(OLEIVERB_SHOW, this);
ASSERT_VALID(pItem);
// As an arbitrary user interface design, this sets the selection
// to the last item inserted
// TODO: reimplement selection as appropriate for your application
m_pSelection = pItem; // set selection to last inserted item
pDoc->UpdateAllViews(NULL);
}
CATCH(CException, e)
{
if (pItem != NULL)
{
ASSERT_VALID(pItem);
pItem->Delete();
}
AfxMessageBox(IDP_FAILED_TO_CREATE);
}
END_CATCH
EndWaitCursor();
}
// The following command handler provides the standard keyboard
// user interface to cancel an in-place editing session. Here,
// the container (not the server) causes the deactivation
void CCEditorScriptView::OnCancelEditCntr()
{
// Close any in-place active item on this view.
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
{
pActiveItem->Close();
}
ASSERT(GetDocument()->GetInPlaceActiveItem(this) == NULL);
}
// Special handling of OnSetFocus and OnSize are required for a container
// when an object is being edited in-place
void CCEditorScriptView::OnSetFocus(CWnd* pOldWnd)
{
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL &&
pActiveItem->GetItemState() == COleClientItem::activeUIState)
{
// need to set focus to this item if it is in the same view
CWnd* pWnd = pActiveItem->GetInPlaceWindow();
if (pWnd != NULL)
{
pWnd->SetFocus(); // don't call the base class
return;
}
}
CView::OnSetFocus(pOldWnd);
}
void CCEditorScriptView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
COleClientItem* pActiveItem = GetDocument()->GetInPlaceActiveItem(this);
if (pActiveItem != NULL)
pActiveItem->SetItemRects();
}
void CCEditorScriptView::OnFilePrint()
{
//By default, we ask the Active document to print itself
//using IOleCommandTarget. If you don't want this behavior
//remove the call to COleDocObjectItem::DoDefaultPrinting.
//If the call fails for some reason, we will try printing
//the docobject using the IPrint interface.
CPrintInfo printInfo;
ASSERT(printInfo.m_pPD != NULL);
if (S_OK == COleDocObjectItem::DoDefaultPrinting(this, &printInfo))
return;
CView::OnFilePrint();
}
void CCEditorScriptView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
ClientToScreen(&point);
OnContextMenu(this, point);
}
void CCEditorScriptView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}
// CCEditorView diagnostics
#ifdef _DEBUG
void CCEditorScriptView::AssertValid() const
{
CView::AssertValid();
}
void CCEditorScriptView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CCEditorDoc* CCEditorScriptView::GetDocument() const // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCEditorDoc)));
return (CCEditorDoc*)m_pDocument;
}
#pragma endregion
#endif //_DEBUG
// CCEditorView message handlers
And this is currently what it outputs:
Now is seems ok, but it only renders it once, meaning if I would click on it(richEdit) nothing would happen, or if I tried to type in the richEdit, nothing would happen as well. So I'm wondering, why? Why doesn't it continue rendering, or updating the view?
Thank You
PS. If you wan't me to post anything, like code, please comment.
So, it seems that I've solved my problem, here's the solution:
I looked at the console and noticed that the window had failed to create. And i came to the solution that the m_rEdit was the fault(by testing). So i figured out that i had to initialize the pointer in the constructor, and use the m_rEdit->Create in the OnInitialUpdate(). And that fixed it.
Anyways, thank you for anyone who tried to solve this mystery.