I think I am missing something small here.
I am trying to make a class which inherits from CStatic with a transparent background. I have managed create an instance of the class and it is displayed in the parent CView. However when I add a OnCtlColor message handler going through the class view on Visual Studio to make the background transparent, it never fires.
Here is a code snippet:
Foo.h
class Foo: public CStatic
{
DECLARE_DYNAMIC(Foo)
public:
Foo();
virtual ~Foo();
virtual void CreateCtrl(CWnd * Parent, POINT TopLeft, SIZE sz);
protected:
DECLARE_MESSAGE_MAP()
public:
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};
Foo.cpp
void Foo::CreateCtrl(CWnd * Parent, POINT TopLeft, SIZE sz)
{
CRect Rect(TopLeft, sz);
Create(pItem->Value->GetBuffer(), WS_CHILD | WS_VISIBLE | SS_CENTER | SS_NOTIFY, Rect, Parent);
ShowWindow(SW_SHOW);
}
BEGIN_MESSAGE_MAP(Foo, CStatic)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
HBRUSH Foo::CtlColor(CDC* pDC, UINT nCtlColor)
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)GetStockObject(NULL_BRUSH);
}
BOOL Foo::OnEraseBkgnd(CDC* pDC)
{
return FALSE;
}
Can anyone suggest what I might be doing wrong?
WM_CTLCOLOR is sent to the parent window, not to the static control.
To catch the message in the static control class, you need to use ON_WM_CTLCOLOR_REFLECT in your message map, see MSDN Docs and use HBRUSH Foo::CtlColor(CDC* pDC, UINT nCtlColor).
Related
I'm working in visual studio and I keep getting these error.
E0322 object of abstract class type "GameState" is not allowed
Error C2259 'GameState': cannot instantiate abstract class
Error C2665 'GameState::GameState': no overloaded function could convert all the argument types
I understand that I need to override the functions from the state class in the gamestate class and I thought that I did that but apparently not. Can anyone see where I am going wrong?
code:
state.h:
class State {
private:
sf::RenderWindow* window;
std::vector<sf::Texture> textures;
public:
State(sf::RenderWindow* window);
virtual ~State(); //this means that all child classes must define these
virtual void endState() = 0;
virtual void update(const float& dt) = 0;
virtual void render(sf::RenderTarget* target = nullptr) = 0; };
state.cpp
#include "State.h"
State::State(sf::RenderWindow* window)
{
this->State::~State(){}
gamestate.h
#include "State.h"
class GameState :
public State
{
private:
public:
GameState(sf::RenderWindow\* window);
virtual \~GameState();
void endState();
void update(const float& dt);
void render(sf::RenderTarget\* target);
};
Gamestate.cpp
#include "GameState.h"
GameState::GameState(sf::RenderWindow\* window)
: State(window){}
GameState::\~GameState(){}
void GameState::endState(){}
void GameState::update(const float& dt){}
void GameState::render(sf::RenderTarget* target = nullptr){}
game.h
#include "GameState.h"
class Game
{
//variables
sf::RenderWindow* window;
sf::Event sfEvent;
sf::Clock dtClock; //frame tracker
float dt; //deltatime
std::stack<State*> states;
//initialization
void initWindow();
void initStates();
public:
Game();
virtual \~Game();
void updateDeltaTime();
void updateSFMLEvents();
void update();
void render();
void run();
};
game.cpp
//I will be leaving out all the unnecessary code to save space
#include "Game.h"
void Game::initStates() {
this->states.push(new GameState(this->window)); //this is where the problem is
}
hovering over GameState says that State::endState()/render()/update() has no override
please help!!!
Take this simple code:
void CRestoreSettingsDlg::OnSize(UINT nType, int cx, int cy)
{
CResizingDialog::OnSize(nType, cx, cy);
m_gridBackupLog.ExpandLastColumn();
}
Why is it being flagged?
C26434 Function 'CRestoreSettingsDlg::OnSize' hides a non-virtual function 'CRestoreDialogDlg::OnSize'.
As you can see, I call the base class method.
Declarations and Definitions
CRestoreSettingsDlg:
public:
afx_msg void OnSize(UINT nType, int cx, int cy);
void CRestoreSettingsDlg::OnSize(UINT nType, int cx, int cy)
{
CResizingDialog::OnSize(nType, cx, cy);
m_gridBackupLog.ExpandLastColumn();
}
CResizingDialog:
public:
afx_msg void OnSize(UINT nType, int cx, int cy);
void CResizingDialog::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
Invalidate(TRUE);
}
The boilerplate base class (afxwin.h) appears to have:
protected:
afx_msg void OnSize(UINT nType, int cx, int cy);
_AFXWIN_INLINE void CWnd::OnSize(UINT, int, int)
{ Default(); }
Inheritance
class CRestoreSettingsDlg : public CResizingDialog
class CResizingDialog : public CDialogEx
C26434 warning documentation links to C.128 C++ Core Guidelines Rule. It explains that to enforce correct usage of virtual functions, non-virtual function hiding should produce a warning.
However, with MFC message maps, you have to name your message handler as specified in macro, OnSize in this case, and, since message handlers already dispatched by a virtual function (that is hidden in *_MESSAGE_MAP() macros), message handler by themselves don't have to be virtual.
So it may be seen as a false alarm. Or maybe seen as violation of the above mentioned C.128 rule by MFC itself. No surprise - MFC is decades older than these guidelines.
So I guess you can go ahead and suppress it for all afx_msg functions. Maybe redefine afx_msg to include __pragma(warning(suppress(...))), or just have suppression around afx_msg block.
Some options for suppression (Godbolt's compiler explorer demo):
#define afx_msg // this is normally defined by MFC
struct base
{
afx_msg void OnSize(){}
};
struct derived1 : base
{
afx_msg void OnSize() {} // produces C26434
};
// Suppression by adding some code:
struct derived2 : base
{
#pragma warning(push)
#pragma warning(disable:26434)
afx_msg void OnSize() {}
#pragma warning(pop)
};
struct derived3 : base
{
[[gsl::suppress(c.128)]] afx_msg void OnSize() {}
};
// Suppression by redefining MFC macro -- dirty but less intrusive:
#undef afx_msg
#define afx_msg __pragma(warning(suppress:26434))
struct derived4 : base
{
afx_msg void OnSize() {}
};
#undef afx_msg
#define afx_msg [[gsl::suppress(c.128)]]
struct derived5 : base
{
afx_msg void OnSize() {}
};
I am getting an exception while running the helloworld MFC application. I have created "Desktop Application" and selected "Empty Project" and then added the required code. I also selected "Use MFC as Shared DLL" in project setting. Added CMyApp and CMainWindow class in code. Also added message map. How do I fix this exception?
code:
Hello.h
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
class CMainWindow : public CFrameWnd
{
public:
CMainWindow();
protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};
Hello.cpp
#include <afxwin.h>
#include "Hello.h"
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
BEGIN_MESSAGE_MAP(CMainWindow,CFrameWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
CMainWindow::CMainWindow()
{
Create(NULL,_T("The Hello Application"));
}
void CMainWindow::OnPaint()
{
CPaintDC dc(this);
CRect rect;
GetClientRect(&rect);
dc.DrawText(_T("Hello MFC"),-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
}
actually i missed following statement in Hello.cpp.
CMyApp myApp;
After adding this statement, it works.
Here is my DirectXBase class header:
#pragma once
#include "pch.h"
struct Vertex
{
XMFLOAT3 pos;
XMFLOAT3 color;
};
struct ModelViewProjectionConstantBuffer
{
DirectX::XMFLOAT4X4 model;
DirectX::XMFLOAT4X4 view;
DirectX::XMFLOAT4X4 projection;
};
ref class DirectXBase abstract
{
internal:
DirectXBase();
virtual void Initialize(
Windows::UI::Core::CoreWindow^ window,
Windows::UI::Xaml::Controls::SwapChainBackgroundPanel^ swapChainPanel,
float dpi);
virtual void HandleDeviceLost();
virtual void CreateDeviceIndependentResources();
virtual void CreateDeviceResources();
virtual void SetDpi(float dpi);
virtual void UpdateForWindowSizeChanged();
virtual void CreateWindowSizeDependentResources();
virtual void Render() = 0;
virtual void Present();
void ValidateDevice();
virtual float ConvertDipsToPixels(float dips);
protected private:
Windows::UI::Core::CoreWindow^ m_window;
Windows::UI::Xaml::Controls::SwapChainBackgroundPanel^ m_swapChainPanel;
// Transforms used for display orientation.
D2D1::Matrix3x2F m_rotationTransform2D;
DirectX::XMFLOAT4X4 m_rotationTransform3D;
DXGI_MODE_ROTATION ComputeDisplayRotation();
//Directx Core Objects
Microsoft::WRL::ComPtr<ID3D11Device1> m_d3dDevice;
Microsoft::WRL::ComPtr<ID3D11DeviceContext1> m_d3dContext;
Microsoft::WRL::ComPtr<IDXGISwapChain1> m_swapChain;
Microsoft::WRL::ComPtr<ID3D11RenderTargetView> m_d3dRenderTargetView;
// Cached renderer properties.
D3D_FEATURE_LEVEL m_featureLevel;
Windows::Foundation::Size m_renderTargetSize;
Windows::Foundation::Rect m_windowBounds;
float m_dpi;
Windows::Graphics::Display::DisplayOrientations m_orientation;
bool m_stereoEnabled;
// Direct3D Rendering Objects. Required for 3D.
Microsoft::WRL::ComPtr<ID3D11DepthStencilView> m_d3dDepthStencilView;
// Transform used for display orientation.
DirectX::XMFLOAT4X4 m_orientationTransform3D;
};
I get the following error message:
syntax error : missing ';' before identifier 'pos'
I have no idea why it's not recognizing my struct. The funny thing is, I just copied it and pasted it from the header of a CubeRenderer class that inherits from this one so that I can have access to these structs from any inheriting class...the code ran as copied about five minutes ago.
In case it's helpful, here are my two child class headers with the structs moved to those headers, which compiles and runs fine.
CubeRenderer.h:
#pragma once
#include "DirectXBase.h"
#include <DirectXMath.h>
using namespace DirectX;
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
struct CubeVertex
{
XMFLOAT3 pos;
XMFLOAT3 color;
};
struct CubeMVPBuffer
{
DirectX::XMFLOAT4X4 model;
DirectX::XMFLOAT4X4 view;
DirectX::XMFLOAT4X4 projection;
};
ref class CubeRenderer : public DirectXBase
{
internal:
CubeRenderer();
virtual void CreateDeviceResources() override;
virtual void CreateWindowSizeDependentResources() override;
virtual void Render() override;
void Update(float timeTotal, float timeDelta);
private:
bool m_loadingComplete;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer;
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_constantBuffer;
uint32 m_indexCount;
CubeMVPBuffer m_constantBufferData;
};
HillRenderer.h:
#pragma once
#include "DirectXBase.h"
#include <DirectXMath.h>
using namespace DirectX;
#define CUSTOMFVF (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
struct HillVertex
{
XMFLOAT3 pos;
XMFLOAT3 color;
};
struct HillMVPBuffer
{
DirectX::XMFLOAT4X4 model;
DirectX::XMFLOAT4X4 view;
DirectX::XMFLOAT4X4 projection;
};
ref class HillRenderer : public DirectXBase
{
internal:
HillRenderer();
virtual void CreateDeviceResources() override;
virtual void CreateWindowSizeDependentResources() override;
virtual void Render() override;
void Update(float timeTotal, float timeDelta);
private:
bool m_loadingComplete;
Microsoft::WRL::ComPtr<ID3D11InputLayout> m_inputLayout;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_vertexBuffer;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_indexBuffer;
Microsoft::WRL::ComPtr<ID3D11VertexShader> m_vertexShader;
Microsoft::WRL::ComPtr<ID3D11PixelShader> m_pixelShader;
Microsoft::WRL::ComPtr<ID3D11Buffer> m_constantBuffer;
uint32 m_indexCount;
HillMVPBuffer m_constantBufferData;
float GetHeight(float x, float z) const
{
return 0.3f*(z*sinf(0.1f*x) + x*cosf(0.1f*z));
}
};
Your struct type doesn't "work" is because when you declare that struct, compiler doesn't know (yet) what XMFLOAT3 means.
Before you can use XMFLOAT3 type, it has to be declared somewhere. My guess is it is declared within DirectXMath.h #include DirectXMath.h at the beginning of DirectXBase.h, and it should work.
I have list box CListBox in which i need to specify the color of individual list item according to some condition. How can i achieve this.
Im running VS2005.
The application is a WTL Dialog based app.
You can create your own listbox(Ex:CColorListBox)
ColorListBox.h
class CColorListBox : public CListBox
{
// Construction
public:
CColorListBox();
// Attributes
public:
// Operations
public:
int AddString( LPCTSTR lpszItem, COLORREF rgb);
int InsertString( int nIndex, LPCTSTR lpszItem, COLORREF rgb);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CColorListBox)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CColorListBox();
// Generated message map functions
protected:
//{{AFX_MSG(CColorListBox)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
ColorListBox.cpp
Here is an idea not exact code............
int CColorListBox::AddString( LPCTSTR lpszItem,COLORREF rgb )
{
int item = AddString(lpszItem);
if(item >=0)
SetItemData(item,rgb);
return item;
}
int CColorListBox::InsertString( int nIndex, LPCTSTR lpszItem, COLORREF rgb)
{
int item = ((CListBox*)this)->InsertString(nIndex,lpszItem);
if(item >=0)
SetItemData(item,rgb);
return item;
}
void CColorListBox::DrawItem(LPDRAWITEMSTRUCT lpdis)
{
}
This is what i did to implement the same functionality in ListViewCtrl.
I wrote a class to extend the CListViewCtrl.
class CListViewCtrlEx: public CWindowImpl<CListViewCtrlEx, CListViewCtrl>, public CCustomDraw<CListViewCtrlEx>
{
public:
BEGIN_MSG_MAP(CListViewCtrlEx)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
CHAIN_MSG_MAP_ALT(CCustomDraw<CListViewCtrlEx>, 1)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bHandled);
DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw);
DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw);
void ForceMeasureItemMessage();
void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/);
BOOL DeleteItem(int nItem);
void GetCellRect(int header_column, const CRect& item_rect, CRect& cell_rect);
};
The complete code is HERE.