I'm currently developing a custom control that derives from CStatic MFC class (Smart Device C++ project). I have created the control class using VC++ MFC class wizard, selecting CStatic class as its base class. I have used Class View to add OnSize event handler for my control class (I 开发者_C百科have selected WM_SIZE message from messages list), and new OnSize method has been created by Visual Studio along with ON_WM_SIZE() statement between BEGIN_MESSAGE_MAP(...) and END_MESSAGE_MAP(). The problem is that my control does not receive WM_SIZE thus OnSize method is never called - I used MoveWindow to change size of my control - its size changes as I have seen on dialog window but WM_SIZE message is never being sent. When I send WM_SIZE through SendMessage or PostMessage function - the control OnSize method is called normally. What do I wrong? I've read MSDN docs about CStatic control and there is no information that WM_SIZE message is never sent to a static control window.
Sorry for my bad English.
For a Windows dialog based project I've tested what you describe. I receive WM_SIZE messages in the custom control after a call of MoveWindow. Can you post a few pieces of your source code, especially for the dialog class where you use your custom Static control for your test?
Update after you posted your code
Did you run this in a debugger? I'm wondering why you don't get immediately an exception when the dialog is opened because CThreatSelection::OnSize is fired as one of the first events, even before the window handle threatGrid.m_hWnd
of your control exists at all. So calling threatGrid.MoveWindow
in your OnSize dialog event should cause an exception when the dialog opens.
I'm not sure what you are trying to achieve but it looks that you want to resize your custom Static according to the dialog size as soon as the dialog opens:
For this a possible alternative could be: Remove CThreatSelection::OnSize
and place in CThreatSelection::OnInitDialog
instead:
CThreatSelection::OnInitDialog()
{
CDialog::OnInitDialog();
// ... perhaps other Init-Stuff...
CRect rect;
GetClientRect(&rect);
threatGrid.MoveWindow(0,0, rect.Width(), rect.Height(), FALSE);
return TRUE;
}
Here you can call threatGrid.MoveWindow because the Window Handle threatGrid.m_hWnd
is already created in OnInitDialog
.
Below is a header of my CDialog based window generated by MFC wizard
#pragma once
#include "threatgrid.h"
#define COLUMN_COUNT 4
// CThreatSelection dialog
class CThreatSelection : public CDialog
{
DECLARE_DYNAMIC(CThreatSelection)
public:
CThreatSelection(CWnd* pParent = NULL); // standard constructor
virtual ~CThreatSelection();
// Dialog Data
enum { IDD = IDD_THSELECT };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
virtual BOOL OnInitDialog();
private:
public:
// My custom cotrol field
CThreatGrid threatGrid;
afx_msg void OnSize(UINT nType, int cx, int cy);
};
Here is te body:
// ThreatSelection.cpp : implementation file
//
#include "stdafx.h"
#include "SpeedNotifyNative.h"
#include "ThreatSelection.h"
// CThreatSelection dialog
IMPLEMENT_DYNAMIC(CThreatSelection, CDialog)
CThreatSelection::CThreatSelection(CWnd* pParent /*=NULL*/)
: CDialog(CThreatSelection::IDD, pParent)
, threatGrid(theApp.imaging, 3)
{
}
CThreatSelection::~CThreatSelection()
{
}
void CThreatSelection::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_THGRID, threatGrid);
}
BEGIN_MESSAGE_MAP(CThreatSelection, CDialog)
ON_WM_SIZE()
END_MESSAGE_MAP()
// CThreatSelection message handlers
BOOL CThreatSelection::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CThreatSelection::OnSize(UINT nType, int cx, int cy)
{
threatGrid.MoveWindow(0,0, cx, cy, FALSE);
//threatGrid.SizeChanged(cx,cy); I use it normally because no WM_SIZE is sent to threatGrid
CDialog::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
}
...And my custom control header:
#pragma once
#include "atltypes.h"
#include "GridIcon.h"
// CThreatGrid
class ImagingSystem;
class CThreatGrid : public CStatic
{
DECLARE_DYNAMIC(CThreatGrid)
public:
CThreatGrid(ImagingSystem* imaging, int cols);
virtual ~CThreatGrid();
protected:
DECLARE_MESSAGE_MAP()
private:
// Obiekt podsystemu obrazowania
ImagingSystem* imaging;
// Ilość kolumn w siatce
int columns;
// Spacing elementów
int spacing;
public:
// Informuje kontrolkę o zmianie rozmiaru - dotychczas nie udało mi się znaleźć rozwiązania dlaczego WM_SIZE nie ejst wysyłane
void SizeChanged(int cx, int cy);
private:
// Aktualny rozmiar - śledzony niezależnie aby uniknąć niepotrzebnych przeładowań obrazków
CSize currSize;
// Lista ikon
std::vector icons;
public:
afx_msg void OnSize(UINT nType, int cx, int cy);
};
...and my custom control body:
// ThreatGrid.cpp : implementation file
//
#include "stdafx.h"
#include "SpeedNotifyNative.h"
#include "ThreatGrid.h"
// CThreatGrid
IMPLEMENT_DYNAMIC(CThreatGrid, CStatic)
CThreatGrid::CThreatGrid(ImagingSystem* imaging, int cols)
: imaging(imaging)
, columns(cols)
{
}
CThreatGrid::~CThreatGrid()
{
}
BEGIN_MESSAGE_MAP(CThreatGrid, CStatic)
ON_WM_SIZE()
END_MESSAGE_MAP()
// Informuje kontrolkę o zmianie rozmiaru - dotychczas nie udało mi się znaleźć rozwiązania dlaczego WM_SIZE nie ejst wysyłane
void CThreatGrid::SizeChanged(int cx, int cy)
{
CSize nSize(cx,cy);
if(nSize != currSize)
{
currSize = nSize;
int wspc = (int)(0.015 * cx);
int hspc = (int)(0.015 * cy);
spacing = (wspc 0 )
{
int rows = (icons.size() + columns - 1) / columns;
int width = (currSize.cx - spacing * (2 + columns - 1)) / columns;
int height = (currSize.cy - spacing * (2 + rows - 1)) / rows;
CSize size;
if ( width Calculate(i / columns, i % columns, abspoint, size, spacing);
}
}
}
}
void CThreatGrid::OnSize(UINT nType, int cx, int cy)
{
CStatic::OnSize(nType, cx, cy);
// NEVER CALLED BY SYSTEM
}
精彩评论