I'm making a dll that in the end will need to had some activeX (in this case a activeX contol from a third party) commands in the Window.
When I test the DLL in a solution I get:
"
Process attachFirst-chance exception at 0x076b00bc in SamsungTester.exe: 0xC0000005: Access violation.
Unhandled exception at 0x076b00bc in SamsungTester.exe: 0xC0000005: Access violation.
"
my code I have a class that extends a CDialog ("myDialog.g")
class myDialog : public CDialog
{
DECLARE_DYNAMIC(myDialog)
public:
myDialog(CWnd* pParent = NULL); // standard constructor
virtual ~myDialog();
// Dialog Data
enum { IDD = IDD_DIALOG1 };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
DECLARE_MESSAGE_MAP()
public:
CXnssdkdevicectrl1 m_ctrlXnsDevice;
long initializeSDK();
};
Then other class that extends a CWinApp
class CMyMFCDLLApp : public CWinApp
{
public:
HANDLE recMutex;
CMyMFCDLLApp();
// Overrides
public:
virtual BOOL InitInstance();
myDialog dlg;
DECLARE_MESSAGE_MAP()
};
then in CPP
#include "stdafx.h"
#include "MyMFCDLL.h"
#include "mydialog.h";
#include "dllDeclaration.h"
#include "Test.h"
#include <initguid.h>
#include "MyMFCDLL_i.c"
// [ XNS ACTIVEX HELP ]
// -----------------------------------------------------------------------
// This files are installed in {$SDK path}\sample_code\include
// You should include this files
// -----------------------------------------------------------------------
#include "XnsCommon.h"
#include "XnsDeviceInterface.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
class CMyMFCDLLModule :
public CAtlMfcModule
{
public:
DECLARE_LIBID(LIBID_MyMFCDLLLib);
DECLARE_REGISTRY_APPID_RESOURCEID(IDR_MYMFCDLL, "{1AFA86BF-3CCC-4A17-B023-F61E8DE38ED6}");};
CMyMFCDLLModule _AtlModule;
BEGIN_MESSAGE_MAP(CMyMFCDLLApp, CWinApp)
END_MESSAGE_MAP()
CMyMFCDLLApp::CMyMFCDLLApp()
{
}
BOOL CMyMFCDLLApp::InitInstance()
{
CWinApp::InitInstance();
AtlAxWinInit();
COleObjectFactory::RegisterAll();
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// Set this to include all the common control classes you want to use
// in your application.
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
AfxOleInit();
AfxEnableControlContainer();
CoInitialize(0);
recMutex=CreateEvent(NULL, FALSE,FALSE, NULL);
return TRUE;
}
long init2(){
AFX_MANAGE_STATE(AfxGetStaticModuleState());
theApp.dlg.Create(myDialog::IDD);
theApp.dlg.ShowWindow(SW_SHOW);
theApp.dlg.initializeSDK();
return 0;
}
When I put the activeX control using in Cdialog this .h is generated:
#pragma once
// ÄÄÇ»ÅÍ¿¡¼ Microsoft Visual C++¸¦ »ç¿ëÇÏ¿© »ý¼ºÇÑ IDispatch ·¡ÆÛ Å¬·¡½ºÀÔ´Ï´Ù.
// Âü°í: ÀÌ ÆÄÀÏÀÇ ³»¿ëÀ» ¼öÁ¤ÇÏÁö ¸¶½Ê½Ã¿À. Microsoft Visual C++¿¡¼
// ÀÌ Å¬·¡½º¸¦ ´Ù½Ã »ý¼ºÇÒ ¶§ ¼öÁ¤ÇÑ ³»¿ëÀ» µ¤¾î¾¹´Ï´Ù.
/////////////////////////////////////////////////////////////////////////////
// CXnssdkdevicectrl ·¡ÆÛ Å¬·¡½ºÀÔ´Ï´Ù.
class CXnssdkdevicectrl : public CWnd
{
protected:
DECLARE_DYNCREATE(CXnssdkdevicectrl)
public:
CLSID const& GetClsid()
{
static CLSID const clsid
= { 0xXPTO, 0xXPTO, 0xXPTO, { 0xXP, 0xXP, 0xXP, 0xXP, 0xXP, 0xXP, 0xXP, 0xXP } };
return clsid;
}
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle,
const RECT& rect, CWnd* pParentWnd, UINT nID,
CCreateContext* pContext = NULL)
{
return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID);
}
BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd,
UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE,
BSTR bstrLicKey = NULL)
{
return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID,
pPersist, bStorage, bstrLicKey);
}
// Ư¼ºÀÔ´Ï´Ù.
public:
// ÀÛ¾÷ÀÔ´Ï´Ù.
public:
// _DXnsSdkDevice
// Functions
//
long Initialize()
{
long result;
InvokeHelper(0x1, DISPATCH_METHOD, VT_I4, (void*)&result, NULL);
return result;
}
To initialize the activeX i call the InitializeSDK that call activeX Initialize function that calls an Invoker:
InvokeHelper(0x1, DISPATCH_METHOD, VT_I4, (void*)&result, NULL);
and then give an exception at:
// make the call
SCODE sc = m_lpDispatch->Invoke(dwDispID, IID_NULL, 0, wFlags,
&dispparams, pvarResult, &excepInfo, &nArgErr);
Related
I try to display a bitmap (gray image) by using MFC but failed. I am using standard windows API in my MFC codes. Below is the code (view.cpp and I put own code in ::OnDraw()):
lpBits is the BYTE array contains the bitmap BYTE data.
When I run the code, I got an "exception thrown" error message and no display of the bitmap (a black bitmap image).
Below you can find the code as well as the error message.
extern BYTE lpBits[510][1024 * 4] = { 0 };
extern CRITICAL_SECTION g_cs;
View.h:
class Cmfc_gui_test1View : public CView
{
protected: // create from serialization only
Cmfc_gui_test1View();
DECLARE_DYNCREATE(Cmfc_gui_test1View)
// Attributes
public:
Cmfc_gui_test1Doc* GetDocument() const;
// Operations
public:
// Overrides
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
// Implementation
public:
virtual ~Cmfc_gui_test1View();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
afx_msg void OnFilePrintPreview();
afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
DECLARE_MESSAGE_MAP()
public:
CBitmap* pBitmap;
CDC* pcdcMem;
CDC* m_pDC;
CRect crect;
CWnd* pwndParent;
int screenX;
int screenY;
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
};
View.cpp:
// Cmfc_gui_test1View drawing
void Cmfc_gui_test1View::OnDraw(CDC* pDC)
{
Cmfc_gui_test1Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: add draw code for native data here
screenX = GetSystemMetrics(SM_CXSCREEN);
screenY = GetSystemMetrics(SM_CYSCREEN);
pBitmap->CreateCompatibleBitmap(m_pDC, 1024, 510); // Error here
pBitmap->SetBitmapBits(510*1024*4, lpBits);
pcdcMem->CreateCompatibleDC(m_pDC);
pcdcMem->SelectObject(pBitmap);
m_pDC->StretchBlt( 0, 0, screenX, screenY, pcdcMem, 0, 0, 1024, 510, SRCCOPY);
pDC->DeleteDC();
}
// Cmfc_gui_test1View message handlers
int Cmfc_gui_test1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
m_pDC = new CClientDC(this);
return 0;
}
Error message occurs when execution hits the line pBitmap->CreateCompatibleBitmap(m_pDC, 1024, 510);:
0x0F7C0AEA (mfc140d.dll)处(位于 mfc_gui_test1.exe 中)引发的异常: 0xC0000005: 读取位置 0xCDCDCDD1 时发生访问冲突。
如有适用于此异常的处理程序,该程序便可安全地继续运行。
Translated:
Exception thrown at 0x0F7C0AEA (mfc140d.dll) (in mfc_gui_test1.exe): 0xC0000005: Access violation while reading location 0xCDCDCDD1.
If there is a handler for this exception, the program can safely continue running.
Problem Dsecription: Application to show an editable table in new window. e.g.: In the following table, I want to be able to edit the register values. I tried to write the application using MFC on Visual Studio 2015 in C++
===========================================================================
I'm working on a MFC application using Visual Studio 2015 in C++
I've created a Dialog Editor In which I want to show a list of registers (type list control) with two columns, one that specifies the registers numbers and a second column to show their values. I've started with the simplest case, and created such list with only one register successfully with the following code:
.cpp file:
#include "stdafx.h"
#include "MFCApplication4.h"
#include "MFCApplication4Dlg.h"
#include "afxdialogex.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_ABOUTBOX };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
CMFCApplication4Dlg::CMFCApplication4Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_MFCAPPLICATION4_DIALOG, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMFCApplication4Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_LIST1, listCtrl);
}
BEGIN_MESSAGE_MAP(CMFCApplication4Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &CMFCApplication4Dlg::OnLvnItemchangedList1)
END_MESSAGE_MAP()
BOOL CMFCApplication4Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
listCtrl.InsertColumn(0, _T("Register Number"));
listCtrl.InsertColumn(1, _T("Register Value"));
listCtrl.SetColumnWidth(0, 200);
listCtrl.SetColumnWidth(1, 400);
int nItem = listCtrl.InsertItem(0, L"0x00");
listCtrl.SetItemText(nItem, 1, L"01000001");
return TRUE; // return TRUE unless you set the focus to a control
}
void CMFCApplication4Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
void CMFCApplication4Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
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;
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
HCURSOR CMFCApplication4Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CMFCApplication4Dlg::OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
// TODO: Add your control notification handler code here
*pResult = 0;
}
.h file:
#pragma once
#include "afxcmn.h"
#include "afxwin.h"
class CMFCApplication4Dlg : public CDialogEx
{
public:
CMFCApplication4Dlg(CWnd* pParent = NULL); // standard constructor
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MFCAPPLICATION4_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
protected:
HICON m_hIcon;
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 OnLvnItemchangedList1(NMHDR *pNMHDR, LRESULT *pResult);
CListCtrl listCtrl;
};
I would like to be able to edit the value of the register by clicking on it once or twice and typing the new value. I tried adding the following function to the header beneath the last line of CListCtrl listCtrl:
afx_msg void RightButtonClick(WPARAM wParam, LPARAM lParam, CPoint point);
the implementation of the function in .cpp file:
afx_msg void CMFCApplication4Dlg::RightButtonClick(WPARAM wParam, LPARAM lParam, CPoint point)
{
//listCtrl.SetFocus();
//CEdit* itemToEdit = listCtrl.EditLabel(1);
// The string replacing the text in the edit control.
LPCTSTR lpszmyString = _T("custom label!");
// If possible, replace the text in the label edit control.
CEdit* pEdit = listCtrl.GetEditControl();
if (pEdit != NULL)
{
pEdit->SetWindowText(lpszmyString);
}
}
and I added the following message to the message map in the .cpp file (last line in the block BEGIN_MESSAGE_MAP):
ON_WM_RBUTTONDBLCLK(LVN_ENDLABELEDIT, IDC_LIST1, &CMFCApplication4Dlg::RightButtonClick)
but unfortunately that's what I'm getting no results.
I've tried reading some more, and I've spent few hours trying to fix it, but haven't succeeded. I've tried to follow the answers to similar posts which are listed below:
Make single items editable in a list control (C++, MFC)
and
How to edit cell in listcontrol mfc?
but I wasn't able to implement the suggestions that were written there, I didn't understand how to connect all the parts of the answers. Additionally, I tried using this guide:
https://www.tutorialspoint.com/mfc/mfc_messages_events.htm
Unfortunately, nothing helped. I have a feeling that I'm missing something fundamental, perhaps I'm not handling the messages as I should. I'd appreciate it if anyone could explain to me what I'm missing and how to fix it.
Please let me know if my question isn't clear enough or if there's any other problem with it, so I'll edit it and get better.
Thank you very much for your time and attention.
I used this guide which solved my problem
I've been trying to write a frame-based MFC application containing a button with simple response to clicks. Unfortunately, it appears like the button does not react to my actions. Here is the application's code:
1) OS.cpp:
#include "stdafx.h"
#include "mfc_includes.h" // some general includes like afxwin.h
#include "OS.h"
#include "MainFrm.h"
#include "button.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
BEGIN_MESSAGE_MAP(COSApp, CWinApp)
END_MESSAGE_MAP()
COSApp::COSApp() {}
COSApp theApp;
btnHelloWorld_t my_button;
BOOL COSApp::InitInstance()
{
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
InitCtrls.dwICC = ICC_WIN95_CLASSES;
InitCommonControlsEx(&InitCtrls);
CWinApp::InitInstance();
CMainFrame* pFrame = new CMainFrame;
if (!pFrame)
return FALSE;
m_pMainWnd = pFrame;
pFrame->Create(L"", L"The application", WS_OVERLAPPEDWINDOW, CRect(100, 100, 500, 500));
my_button.Create(L"Hello World!", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, CRect(30, 30, 150, 80), pFrame, btnHelloWorld_t::GetID());
HFONT font = CreateFont(20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, L"Times New Roman");
SendMessage(my_button.m_hWnd, WM_SETFONT, (WPARAM)font, true);
pFrame->ShowWindow(SW_SHOW);
pFrame->UpdateWindow();
return TRUE;
}
2) OS.h:
class COSApp : public CWinApp
{
public:
virtual BOOL InitInstance();
afx_msg void OnAppAbout();
DECLARE_MESSAGE_MAP()
};
extern COSApp theApp;
3) button.h (containing a custom button class):
#pragma once
#include "mfc_includes.h"
class btnHelloWorld_t : public CButton
{
static const int is_button = 0x200;
static int id;
public:
btnHelloWorld_t()
{
id++;
};
static const int GetID()
{
return id;
};
afx_msg void Click();
DECLARE_MESSAGE_MAP()
};
int btnHelloWorld_t::id = 0x200;
afx_msg void btnHelloWorld_t::Click()
{
SetWindowText(L"Hello!");
}
BEGIN_MESSAGE_MAP(btnHelloWorld_t, CButton)
ON_BN_CLICKED(btnHelloWorld_t::GetID(), &btnHelloWorld_t::Click)
END_MESSAGE_MAP()
Could you tell me what's wrong and how to make the button to change its text after a click? Thanks in advance.
Your btnHelloWorld_t::GetID() is static method!! When you create the first button, GetID() return 201. Then when the message map is called, GetID() return 202. Then if the message map is called again, GetID() return 203. Then 204, 205....
You have to handle BN_CLICKED command in CMainFrame, not btnHelloWorld_t! If the button is clicked, its parent window will get a WM_COMMAND message, with notifyCode == BN_CLICKED and controlID == the ID you passed to CButton::Create().
I created a simple tab control that has 2 tabs (each tab is a different dialog). The thing is that i don't have any idea how to switch between tabs (when the user presses Titlu Tab1 to show the dialog i made for the first tab, and when it presses Titlu Tab2 to show my other dialog). I added a handler for changing items, but i don't know how should i acces some kind of index or child for tabs.
Tab1.h and Tab2.h are headers for dialogs that show only static texts with the name of the each tab.
There may be an obvious answer to my question, but i am a real newbie in c++ and MFC.
This is my header:
// CTabControlDlg.h : header file
//
#pragma once
#include "afxcmn.h"
#include "Tab1.h"
#include "Tab2.h"
// CCTabControlDlg dialog
class CCTabControlDlg : public CDialog
{
// Construction
public:
CCTabControlDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
enum { IDD = IDD_CTABCONTROL_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:
CTabCtrl m_tabcontrol1;
CTab1 m_tab1;
CTab2 m_tab2;
afx_msg void OnTcnSelchangeTabcontrol(NMHDR *pNMHDR, LRESULT *pResult);
};
And this is the .cpp:
// CTabControlDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CTabControl.h"
#include "CTabControlDlg.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()
// CCTabControlDlg dialog
CCTabControlDlg::CCTabControlDlg(CWnd* pParent /*=NULL*/)
: CDialog(CCTabControlDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CCTabControlDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TABCONTROL, m_tabcontrol1);
}
BEGIN_MESSAGE_MAP(CCTabControlDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_NOTIFY(TCN_SELCHANGE, IDC_TABCONTROL, &CCTabControlDlg::OnTcnSelchangeTabcontrol)
END_MESSAGE_MAP()
// CCTabControlDlg message handlers
BOOL CCTabControlDlg::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
CTabCtrl* pTabCtrl = (CTabCtrl*)GetDlgItem(IDC_TABCONTROL);
m_tab1.Create(IDD_TAB1, pTabCtrl);
TCITEM item1;
item1.mask = TCIF_TEXT | TCIF_PARAM;
item1.lParam = (LPARAM)& m_tab1;
item1.pszText = _T("Titlu Tab1");
pTabCtrl->InsertItem(0, &item1);
//Pozitionarea dialogului
CRect rcItem;
pTabCtrl->GetItemRect(0, &rcItem);
m_tab1.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
m_tab1.ShowWindow(SW_SHOW);
// al doilea tab
m_tab2.Create(IDD_TAB2, pTabCtrl);
TCITEM item2;
item2.mask = TCIF_TEXT | TCIF_PARAM;
item2.lParam = (LPARAM)& m_tab1;
item2.pszText = _T("Titlu Tab2");
pTabCtrl->InsertItem(0, &item2);
//Pozitionarea dialogului
//CRect rcItem;
pTabCtrl->GetItemRect(0, &rcItem);
m_tab2.SetWindowPos(NULL, rcItem.left, rcItem.bottom + 1, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
m_tab2.ShowWindow(SW_SHOW);
return TRUE; // return TRUE unless you set the focus to a control
}
void CCTabControlDlg::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 CCTabControlDlg::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
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CCTabControlDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CCTabControlDlg::OnTcnSelchangeTabcontrol(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: Add your control notification handler code here
*pResult = 0;
}
You can do this automatically in MFC by making the parent dialog a CPropertySheet and the contained dialogs CPropertyPage.
With the way you have it structured currently, you should do a ShowWindow for each of the dialogs with one set to SW_SHOW and the other to SW_HIDE in your OnTcnSelchangeTabcontrol function.
You should add your Tabcontrol click event and do the following codes. Dialog pointers pTab1 and pTab2 for each dialog/tab.
void CYourClass::OnNMClickTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
pTab1->ShowWindow(SW_HIDE);
pTab2->ShowWindow(SW_HIDE);
for(int i=0;i<2;i++)
{
m_tbCtrl.HighlightItem(i,FALSE);
}
switch(m_tbCtrl.GetCurSel())
{
case 0: pTab1->ShowWindow(SW_SHOW);break;
case 1: pTab2->ShowWindow(SW_SHOW);break;
}
m_tbCtrl.HighlightItem(m_tbCtrl.GetCurSel(),TRUE);
*pResult = 0;
}
I'm having a very frustrating issue setting up a DirectX 9 (irrelevant to the issue.. I think) framework in VS 2010. Here is my DirectX framework:
#ifndef _DX9_H_
#define _DX9_H_
// window includes
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
// required for ush typedef and window properties to setup backbuffer
#include "sys_params.h"
// directx9 includes
#define DIRECTINPUT_VERSION 0x0800
#include <d3dx9.h>
#include <dinput.h>
#include <DxErr.h>
#include <vector>
#include <iterator>
// directx9 libraries
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")
#pragma comment(lib, "dxerr.lib")
namespace nsdx9
{
using nssysprms::ush;
#define CheckHR(hr) CheckForDXError(__FILE__, __LINE__, hr)
class DX9
{
public:
DX9(HINSTANCE& inst, int cmdShow, const std::string& title, ush wndwidth, ush wndheight, short wndx, short wndy);
~DX9();
// windows message processor
UINT ProcessMessages();
// --- DIRECTX GAME FUNCTIONS --- //
// input functions
void InputUpdate();
BYTE KeyHeld(ush key);
bool KeyPressed(ush key);
// sprite functions
const LPD3DXSPRITE& GetSpriteInterface();
void SpriteBeginDraw(DWORD flags = D3DXSPRITE_ALPHABLEND);
void SpriteEndDraw();
// font functions
void MakeFont(int height, int width, UINT weight = FW_DONTCARE, LPCSTR face = "Calibri", bool italic = false);
const LPD3DXFONT& GetFontAtIndex(ush index);
const std::vector<LPD3DXFONT>& GetFontVector();
// --- END DIRECTX GAME FUNCTIONS --- //
private:
// --- WINDOW FUNCTIONS/VARIABLES --- //
WNDCLASSEX _wc;
HWND _hwnd;
MSG _msg;
HINSTANCE _inst;
std::string _title;
static LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wprm, LPARAM lprm);
// --- END WINDOW FUNCTIONS/VARIABLES --- //
// --- DIRECTX FUNCTIONS/VARIABLES --- //
// D3D interfaces
LPDIRECT3D9 _d3d;
LPDIRECT3DDEVICE9 _d3ddev;
D3DPRESENT_PARAMETERS _d3dpp;
// directinput interfaces
LPDIRECTINPUT8 _dInput;
LPDIRECTINPUTDEVICE8 _diMouse;
LPDIRECTINPUTDEVICE8 _diKeyboard;
DIMOUSESTATE _mouseState;
BYTE _keys[256];
bool _keyStates[256];
bool _keyboardStateChanged;
void AcquireInputDevice(const LPDIRECTINPUTDEVICE8& dev);
// sprite interfaces
LPD3DXSPRITE _spriteBatch;
// font vector
std::vector<LPD3DXFONT> _fonts;
// hresult checker, for debugging only
void CheckForDXError(const char *file, int line, HRESULT hr);
// --- END DIRECTX FUNCTIONS/VARIABLES --- //
};
/*=================================================*/
/*--------------DIRECTX CONSTRUCTOR----------------*/
/*=================================================*/
DX9::DX9(HINSTANCE& inst, int cmdShow, const std::string& title, ush wndwidth, ush wndheight, short wndx, short wndy)
{
/*=================================================*/
/*--------------WINDOW INITIALIZATION--------------*/
/*=================================================*/
_title = title;
_inst = inst;
// init window class struct
_wc.cbClsExtra = NULL;
_wc.cbSize = sizeof(WNDCLASSEX);
_wc.cbWndExtra = NULL;
_wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
_wc.hCursor = LoadCursor(NULL, IDC_ARROW);
_wc.hIcon = NULL;
_wc.hIconSm = NULL;
_wc.hInstance = inst;
_wc.lpfnWndProc = (WNDPROC)WinProc;
_wc.lpszClassName = title.c_str();
_wc.lpszMenuName = NULL;
_wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClassEx(&_wc);
// create handle to the window
_hwnd = CreateWindow(title.c_str(),
title.c_str(),
WS_OVERLAPPEDWINDOW,
wndx,
wndy,
wndwidth,
wndheight,
NULL,
NULL,
inst,
NULL);
// required to make the window show up
ShowWindow(_hwnd, cmdShow);
UpdateWindow(_hwnd);
/*=================================================*/
/*--------------END WINDOW INITIALIZATION----------*/
/*=================================================*/
/*=================================================*/
/*--------------DIRECTX INITIALIZATION-------------*/
/*=================================================*/
// --- INITIALIZE DIRECTX9 VARIABLES --- //
SecureZeroMemory(&_d3dpp, sizeof(_d3dpp));
SecureZeroMemory(&_mouseState, sizeof(_mouseState));
SecureZeroMemory(&_keys, sizeof(_keys));
for (int i = 0; i < 256; i++)
{
_keyStates[i] = true;
}
_d3d = NULL;
_d3ddev = NULL;
_dInput = NULL;
_diMouse = NULL;
_diKeyboard = NULL;
_keyboardStateChanged = false;
_spriteBatch = NULL;
// --- END INITIALIZE DIRECTX9 VARIABLES --- //
// --- DIRECTX9 INITIALIZATION --- //
_d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (!_d3d)
{
OutputDebugString("Error: Failed to create Direct3D.\n");
}
// set d3d present parameters
_d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
_d3dpp.BackBufferCount = 1;
_d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
_d3dpp.BackBufferHeight = nssysprms::WND_HEIGHT;
_d3dpp.BackBufferWidth = nssysprms::WND_WIDTH;
_d3dpp.EnableAutoDepthStencil = 1;
_d3dpp.Flags = D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL;
//_d3dpp.FullScreen_RefreshRateInHz
_d3dpp.hDeviceWindow = _hwnd;
//_d3dpp.MultiSampleQuality
//_d3dpp.MultiSampleType
_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
_d3dpp.Windowed = nssysprms::isWindowed;
// create d3d device
CheckHR(_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, _hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &_d3dpp, &_d3ddev));
// --- END DIRECTX9 INITIALIZATION --- //
// --- INITIALIZE DIRECTINPUT --- //
CheckHR(DirectInput8Create(inst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&_dInput, NULL));
// create mouse and keyboard
CheckHR(_dInput->CreateDevice(GUID_SysKeyboard, &_diKeyboard, NULL));
CheckHR(_dInput->CreateDevice(GUID_SysMouse, &_diMouse, NULL));
// initialize keyboard
CheckHR(_diKeyboard->SetDataFormat(&c_dfDIKeyboard));
CheckHR(_diKeyboard->SetCooperativeLevel(_hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND));
AcquireInputDevice(_diKeyboard);
// initialize mouse
CheckHR(_diMouse->SetDataFormat(&c_dfDIMouse));
CheckHR(_diMouse->SetCooperativeLevel(_hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND));
AcquireInputDevice(_diMouse);
// create sprite object
CheckHR(D3DXCreateSprite(_d3ddev, &_spriteBatch));
// --- END INITIALIZE DIRECTINPUT --- //
/*=================================================*/
/*--------------END DIRECTX INITIALIZATION---------*/
/*=================================================*/
}
/*=================================================*/
/*--------------END DIRECTX CONSTRUCTOR------------*/
/*=================================================*/
/*=================================================*/
/*--------------DIRECTX DESTRUCTOR-----------------*/
/*=================================================*/
DX9::~DX9()
{
// set all stack variables to NULL
SecureZeroMemory(&_d3dpp, sizeof(_d3dpp));
SecureZeroMemory(&_mouseState, sizeof(_mouseState));
SecureZeroMemory(&_keys, sizeof(_keys));
SecureZeroMemory(&_keyStates, sizeof(_keyStates));
// free all the D3D interfaces from memory
if (!_fonts.empty())
{
for (std::vector<LPD3DXFONT>::iterator it = _fonts.begin(); it != _fonts.end(); it++)
{
// SOLVEPROBLEM figure out why this doesn't work
//*it->OnLostDevice();
}
_fonts.erase(_fonts.begin(), _fonts.end() - 1);
}
if (_spriteBatch != NULL)
{
_spriteBatch->Release();
_spriteBatch = NULL;
}
if (_diKeyboard != NULL)
{
_diKeyboard->Release();
_diKeyboard = NULL;
}
if (_diMouse != NULL)
{
_diMouse->Release();
_diMouse = NULL;
}
if (_d3ddev != NULL)
{
_d3ddev->Release();
_d3ddev = NULL;
}
if (_d3d != NULL)
{
_d3d->Release();
_d3d = NULL;
}
// free the window class from memory
UnregisterClass(_title.c_str(), _inst);
}
/*=================================================*/
/*--------------END DIRECTX DESTRUCTOR-------------*/
/*=================================================*/
/*=================================================*/
/*--------------HRESULT ERROR CHECK----------------*/
/*=================================================*/
void DX9::CheckForDXError(const char *file, int line, HRESULT hr)
{
if (SUCCEEDED(hr))
{
return;
}
// Get the direct X error and description
char desc[1024];
sprintf_s(desc,"(DX) %s - %s", DXGetErrorString(hr), DXGetErrorDescription(hr));
// Output the file and line number in the correct format + the above DX error
char buf[2048];
sprintf_s(buf,"%s(%d) : Error: %s\n", file, line, desc);
OutputDebugString(buf);
}
/*=================================================*/
/*--------------END HRESULT ERROR CHECK------------*/
/*=================================================*/
/*=================================================*/
/*--------------MESSAGE PROCESSOR------------------*/
/*=================================================*/
UINT DX9::ProcessMessages()
{
if (PeekMessage(&_msg, NULL, NULL, NULL, PM_REMOVE))
{
TranslateMessage(&_msg);
DispatchMessage(&_msg);
}
return _msg.message;
}
/*=================================================*/
/*--------------END MESSAGE PROCESSOR--------------*/
/*=================================================*/
/*=================================================*/
/*--------------MESSAGE HANDLER--------------------*/
/*=================================================*/
LRESULT CALLBACK DX9::WinProc(HWND hwnd, UINT msg, WPARAM wprm, LPARAM lprm)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, msg, wprm, lprm);
}
/*=================================================*/
/*--------------END MESSAGE HANDLER----------------*/
/*=================================================*/
/*=================================================*/
/*--------------DIRECTINPUT FUNCTIONS--------------*/
/*=================================================*/
// for init only, helper function to initially acquire the
// mouse and keyboard
void DX9::AcquireInputDevice(const LPDIRECTINPUTDEVICE8& dev)
{
// loop and attempt to acquire the device until success
while (FAILED(dev->Acquire()))
{
dev->Acquire();
}
}
// update the state of the mouse and keyboard
void DX9::InputUpdate()
{
_diKeyboard->GetDeviceState(sizeof(_keys), (LPVOID)_keys);
_diMouse->GetDeviceState(sizeof(_mouseState), (LPVOID)&_mouseState);
// after directinput has been updated, check to see if any keys are no,
// longer pressed, and reset the keystate array at that key's index if,
// this is the case
// keystates true = key is available for key press
if (_keyboardStateChanged)
{
for (int i = 0; i < 256; i++)
{
if (!KeyHeld(i))
{
_keyStates[i] = true;
}
}
}
_keyboardStateChanged = false;
}
// captures a key being held down
BYTE DX9::KeyHeld(ush key)
{
return _keys[key] & 0x80;
}
// captures a single key press
bool DX9::KeyPressed(ush key)
{
if (KeyHeld(key) && _keyStates[key])
{
_keyStates[key] = false;
return true;
}
else
{
if (!KeyHeld(key) && !_keyStates[key])
{
_keyboardStateChanged = true;
}
return false;
}
}
/*=================================================*/
/*--------------END DIRECTINPUT FUNCTIONS----------*/
/*=================================================*/
/*=================================================*/
/*--------------SPRITE FUNCTIONS-------------------*/
/*=================================================*/
// returns the sprite interface
const LPD3DXSPRITE& DX9::GetSpriteInterface()
{
return _spriteBatch;
}
// begin drawing with the sprite batch
void DX9::SpriteBeginDraw(DWORD flags)
{
_spriteBatch->Begin(flags);
}
// end sprite batch drawing
void DX9::SpriteEndDraw()
{
_spriteBatch->End();
}
/*=================================================*/
/*--------------END SPRITE FUNCTIONS---------------*/
/*=================================================*/
/*=================================================*/
/*--------------FONT FUNCTIONS---------------------*/
/*=================================================*/
// create a font
void DX9::MakeFont(int height, int width, UINT weight, LPCSTR face, bool italic)
{
LPD3DXFONT newfont;
CheckHR(D3DXCreateFont(_d3ddev,
height,
width,
weight,
0,
italic,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
CLEARTYPE_QUALITY,
DEFAULT_PITCH | FF_DONTCARE,
face,
&newfont));
_fonts.push_back(newfont);
}
// gets a font at the specified index
const LPD3DXFONT& DX9::GetFontAtIndex(ush index)
{
return _fonts[index];
}
const std::vector<LPD3DXFONT>& DX9::GetFontVector()
{
return _fonts;
}
/*=================================================*/
/*--------------END FONT FUNCTIONS-----------------*/
/*=================================================*/
}
#endif
This really doesn't do anything but create and initialize a window, DirectX and some basic DirectX functions.
The actual error is this:
Error 1 error LNK2005: "public: __thiscall nsdx9::DX9::DX9(struct HINSTANCE__ * &,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,unsigned short,unsigned short,short,short)" (??0DX9#nsdx9##QAE#AAPAUHINSTANCE__##HABV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##GGFF#Z) already defined in game_manager.obj C:\Users\JAREK\documents\visual studio 2010\Projects\example\example\main.obj
This error is repeated for every single function in dx9.h. If I ONLY include dx9.h in main.cpp, I do not get this error. It is only if I include dx9.h in any other cpp file, or use any of the parameters in dx9.h in cpp files that have access to dx9.h by being included after dx9.h in main.cpp that I get this error. This sounds confusing, so here are some samples from other parts of the program:
main.cpp:
#include "sys_params.h"
#include "dx9.h"
#include "game_manager.h"
int WINAPI WinMain (HINSTANCE inst, HINSTANCE pinst, LPSTR cmdLine, int cmdShow)
{
// state of the program
bool appEnd = false;
// create and initialize the window and directx9
nsdx9::DX9* _dx9 = new nsdx9::DX9(inst, cmdShow, nssysprms::GAME_TITLE,
nssysprms::WND_WIDTH, nssysprms::WND_HEIGHT,
nssysprms::WND_POS_X, nssysprms::WND_POS_Y);
// create and initialize the game manager
Game_Manager* _mngr = new Game_Manager(_dx9);
// Windows message handler
// also the entry point for the main game loop
while (_dx9->ProcessMessages() != WM_QUIT && !appEnd)
{
if (!_mngr->Game_Run())
{
appEnd = true;
}
}
// clean up everything
delete _mngr;
delete _dx9;
return 0;
}
game_manager.h:
#ifndef _GAME_MANAGER_H_
#define _GAME_MANAGER_H_
#include <stack>
#include <vector>
#include "dx9.h"
#include "screen.h"
#include "message_handler.h"
class Game_Manager
{
public:
Game_Manager(nsdx9::DX9* dx9);
~Game_Manager();
bool Game_Run();
private:
nsdx9::DX9* _dx9;
std::stack<Screen*> _screens;
Message_Handler* _msg_hnd;
// *** DECLARE SCREENS HERE *** //
void InitFonts();
void InitScreens();
};
#endif
This should be what is actually causing the issue. The issue is originating from main.cpp through game_manager.h. Nothing I've tried has solved the problem for me. I've included header guards in dx9.h, so I have no idea what could be causing this. if you guys need more information, please let me know. Thanks!
Your definitions of the DX9 methods (as opposed to just the class definition) seem to be in the dx9.h header file - so you violate C++'s one-definition rule when you include dx9.h in multiple .cpp files. To solve this, move the method implementations into a .cpp file (e.g. dx9.cpp).
Don't include the implementation in the header file. This causes the implementation to be compiled again everywhere it is included.
for example:
/*=================================================*/
/*--------------DIRECTX CONSTRUCTOR----------------*/
/*=================================================*/
DX9::DX9(HINSTANCE& inst, int cmdShow, const std::string& title, ush wndwidth, ush wndheight, short wndx, short wndy)
{
.... et al
put that in it's own cpp