|
Hi,
In my project, I need code such as:
one head file:
#include "B.h"
class CA {
void fun(CB *pB);
}
Another head file:
#include "A.h"
class CB {
void fun2(CA *pA);
}
but the including each other will cause compiler error, How to solve that?
thanks.
|
|
|
|
|
You don't need to include the headers, just define the class'.
i.e.
// File: CA.h
class CB;
class CA {
void fun(CB *pB);
}
// File: CB.h
class CA;
class CB {
void fun2(CA *pA);
}
...cmk
Save the whales - collect the whole set
|
|
|
|
|
Thanks a lot.it really helped
|
|
|
|
|
In addition to doing the above suggestion, add #pragma once to the top of your headers.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
I am trying to compile a project written in Visual C++ 6 in Visual Studio 2005.
And I have an error, saying
error C2664: 'localtime' : cannot convert parameter 1 from 'long *' to 'const time_t *'
Below is the snippet of the file
long totalSeconds = (long)(dSeconds +.5);
struct tm *myTime = localtime(&totalSeconds);//Convert to local tim
Anybody can help me?
Yonggoo
|
|
|
|
|
Short answer:
The prototype for localtime is:
struct tm *localtime(const time_t *timer);
You are passing a long* not a time_t*.
Longer answer:
time_t is a long in 32-bit OS's but a __int64 in 64-bit OS's.
As time_t has been a long for a long time (no pun intended) many developers found it more convenient to just use a long.
In VS2005 time_t is a __int64 unless _USE_32BIT_TIME_T is defined.
So, in reality you are passing a long* to a function expecting a __int64*.
Just use time_t, there is a reason it is defined as a distinct type.
e.g.
time_t totalSeconds = (time_t)(dSeconds +.5);
struct tm *myTime = localtime(&totalSeconds);
...cmk
Save the whales - collect the whole set
|
|
|
|
|
Anyone recommend a profiler that will work with unmanaged C++/VS 2005?
Compuware seems to have bailed out on releasing the free community edition that was available for 2002/2003.
"My dog worries about the economy. Alpo is up to 99 cents a can. That's almost seven dollars in dog money" - Wacky humour found in a business magazine
|
|
|
|
|
Unfortunately, Compuware doesn't have a free version since their latest version is really nice.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
I have an app written in VC++ 6.0 on XP Sp2. The app makes a socket connection to a service under normal conditions. If the service is stopped the app destroys the socket, recreates a new one and retries. The deletion, recreation, reconnect continues until successful.
However, I notice that there is an apparent memory leak. I've checked out
Process/Private Bytes & Process/Working Set using Perfmon. Both are seen to
increase during the reconnection attempts.
Any ideas please.
Dave Regan
|
|
|
|
|
Visual C++ 6.0
I've setup some context-sensitive help functionality for our app. The target window is a CView with a bunch of embedded CWnd objects. When I click on the context-help button in the toolbar, the cursor changes to the arrow/questionmark (like it should). However, if I click somewhere in the view that isn't one of the smaller CWnd's, I have the program displaying a messagebox saying there's no help. Now comes the weird part...
When I click the okay button in the messagebox, the cursor doesn't change back to the standard arrow cursor until I move the mouse over another window.
I've tried this line of code at the end of my OnContextHelp function:
AfxGetApp()->LoadStandardCursor(IDC_ARROW);
but it still doesn't change the cursor. Anyone have any ideas?
------- sig starts
"I've heard some drivers saying, 'We're going too fast here...'. If you're not here to race, go the hell home - don't come here and grumble about going too fast. Why don't you tie a kerosene rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Is your view possibly intercepting and discarding WM_SETCURSOR messages?
Ryan "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"
|
|
|
|
|
Nope, there's no handler at all in the view for WM_SETCURSOR...
And while checking what you mentioned, I realized that I had no call to ::SetCursor(). Duh!
It's fixed now.
------- sig starts
"I've heard some drivers saying, 'We're going too fast here...'. If you're not here to race, go the hell home - don't come here and grumble about going too fast. Why don't you tie a kerosene rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt
"...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
|
|
|
|
Hi,
I am trying to remove a device using the fn,bOk = SetupDiRemoveDevice(hDevInfo,devinfoData[n1]);
as soon as I do this, (I think there are some bugs in its driver) it gets to the found new hardware wizard, and recreats the registries ( for I want to remove that device and delete the registries).
How do I overcome this. I know we can tell device manager to send me all the devices messages so that when I get new hardware message, I can ignore it.
Can anyone help me how to do that?
Thanks in advance.
|
|
|
|
|
Hi, I would like to learn how to change registry entries from a MFC (dialog based) application. I am trying to disable the Task Manager when my application loads and disable it before I exit.
Any help would be greatly apperciated. Thanks,
This is the entry i'm trying to change:
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System]---->DisableTaskMgr
|
|
|
|
|
Use RegSetValueEx(.....) to set the registry value
cheers,
Super
------------------------------------------
Too much of good is bad,mix some evil in it
|
|
|
|
|
Thanks Super, that worked!
|
|
|
|
|
I am using Visual C++ 6.0. I have an MFC Dialog based application. I have an class derived from CDialog called CIntrument that has edit controls. Each edit control has a unique IDD_EDIT identifier and have unique variables defined as Value CString. In a different CDialog box I instantiate an object of type 'CInstrument Inst'. I then use fscanf() to read text from a file into the member variables Inst.m_var_a, Inst.m_var_b, Inst.m_var_c and others. As each item of text is read ALL the member variables change to the value that was just read. I have verified this while stepping through the code one line at a time. I am very confused as to why variables with completely different names would be modified in this fashion.
Thanks
Buck
|
|
|
|
|
Open the resource.h and the .rc file using the text editor and confirm that each edit control really does have a unique ID and that that ID is really a unique value.
Next, check DoDataExchange and verify that the controls and the member variables are being assigned correctly.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Yes, everything seems to be the way you would expect it.
Buck
|
|
|
|
|
Darn, then I'm at a loss without looking at the source.
Could it have to do with how fscanf() is being used?
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Here are the two header and two cpp files. The code that is causing me problems is in the ListOfInstrumentsDlg::OnInitDialog() function at the bottom of this posting.
// Instrument.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CInstrument dialog
class CInstrument : public CDialog
{
// Construction
public:
CInstrument(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CInstrument)
enum { IDD = IDD_DIALOG_INSTRUMENT };
CString m_GPIB;
CString m_Name;
CString m_Type;
CString m_Channels;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CInstrument)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CInstrument)
// NOTE: the ClassWizard will add member functions here
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_INSTRUMENT_H__E23BF332_8005_4295_B743_DDC7DC952923__INCLUDED_)
********************************************************
********************************************************
// Instrument.cpp : implementation file
//
#include "stdafx.h"
#include "ListOfInstruments.h"
#include "Instrument.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CInstrument dialog
CInstrument::CInstrument(CWnd* pParent /*=NULL*/)
: CDialog(CInstrument::IDD, pParent)
{
//{{AFX_DATA_INIT(CInstrument)
m_GPIB = _T("");
m_Name = _T("");
m_Type = _T("");
m_Channels = _T("");
//}}AFX_DATA_INIT
}
void CInstrument::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CInstrument)
DDX_Text(pDX, IDC_EDIT_GPIB, m_GPIB);
DDX_Text(pDX, IDC_EDIT_NAME, m_Name);
DDX_Text(pDX, IDC_EDIT_TYPE, m_Type);
DDX_Text(pDX, IDC_EDIT_CHANNELS, m_Channels);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CInstrument, CDialog)
//{{AFX_MSG_MAP(CInstrument)
// NOTE: the ClassWizard will add message map macros here
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
********************************************************
********************************************************
//
// ListOfInstrumentsDlg.h header file
#include "Instrument.h"
/////////////////////////////////////////////////////////////////////////////
// CListOfInstrumentsDlg dialog
class CListOfInstrumentsDlg : public CDialog
{
// Construction
public:
CListOfInstrumentsDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CListOfInstrumentsDlg)
enum { IDD = IDD_LISTOFINSTRUMENTS_DIALOG };
CListBox m_ListInstruments;
CString m_Transfer;
CString m_Add;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CListOfInstrumentsDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
CInstrument Inst;
private:
// CArray<cinstrument, cinstrument&=""> InstArray;
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CListOfInstrumentsDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnDblclkListInstruments();
afx_msg void OnBtnTransfer();
afx_msg void OnBtnAdd();
afx_msg void OnBtnDelete();
afx_msg void OnBtnNew();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_LISTOFINSTRUMENTSDLG_H__11140619_DB17_44D5_BA7D_0A965B24C920__INCLUDED_)
********************************************************
********************************************************
// ListOfInstrumentsDlg.cpp : implementation file
//
#include "stdafx.h"
#include "ListOfInstruments.h"
#include "ListOfInstrumentsDlg.h"
#include "NewInstrument.h"
//#include "Instrument.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CListOfInstrumentsDlg dialog
CListOfInstrumentsDlg::CListOfInstrumentsDlg(CWnd* pParent /*=NULL*/)
: CDialog(CListOfInstrumentsDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CListOfInstrumentsDlg)
m_Transfer = _T("");
m_Add = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CListOfInstrumentsDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CListOfInstrumentsDlg)
DDX_Control(pDX, IDC_LIST_INSTRUMENTS, m_ListInstruments);
DDX_Text(pDX, IDC_EDIT_TRANSFER, m_Transfer);
DDX_Text(pDX, IDC_EDIT_ADD, m_Add);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CListOfInstrumentsDlg, CDialog)
//{{AFX_MSG_MAP(CListOfInstrumentsDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_LBN_DBLCLK(IDC_LIST_INSTRUMENTS, OnDblclkListInstruments)
ON_BN_CLICKED(IDC_BTN_TRANSFER, OnBtnTransfer)
ON_BN_CLICKED(IDC_BTN_ADD, OnBtnAdd)
ON_BN_CLICKED(IDC_BTN_DELETE, OnBtnDelete)
ON_BN_CLICKED(IDC_BTN_NEW, OnBtnNew)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CListOfInstrumentsDlg message handlers
BOOL CListOfInstrumentsDlg::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
// CString* m_InstrumentType;
// CString* m_InstrumentName;
// CString* m_GPIB;
// CString* m_Channels;
CString* m_Comma;
CString* m_Return;
FILE* infile;
char* config_file = "Config.txt";
infile = fopen(config_file, "r");
int end_of_file = 0;
CInstrument Inst;
// Here is where the input read from the Config.txt file and stored in the respective variables.
while (!end_of_file)
{
fscanf(infile, "%[^,]", Inst.m_Type);
// fscanf(infile, "%[^,]", &m_InstrumentType);
fscanf(infile, "%[,]", &m_Comma);
fscanf(infile, "%[^,]", Inst.m_Name);
// fscanf(infile, "%[^,]", &m_InstrumentName);
fscanf(infile, "%[,]", &m_Comma);
fscanf(infile, "%[^,]", Inst.m_GPIB);
// fscanf(infile, "%[^,]", &m_GPIB);
fscanf(infile, "%[,]", &m_Comma);
fscanf(infile, "%[^\n]", Inst.m_Channels);
// fscanf(infile, "%[^\n]", &m_Channels);
fscanf(infile, "%[\n]", &m_Return);
// InstArray.Add();
if (feof(infile))
end_of_file = 1;
}
return TRUE; // return TRUE unless you set the focus to a control
}
Buck
|
|
|
|
|
Of immediate concern, and I think the ultimate cause, is that you are using the CString variables directly, without getting the buffers. This is overwriting the null string the CString variables point to by default.
You should do:
fscanf(infile, "%s", Inst.m_Type.GetBuffer(32));<br />
Inst.m_Type.ReleaseBuffer();
This is rather unsafe since it assumes it will read only 32 characters.
With VS 2007, you could do:
fscanf_s(infile, "%s", Inst.m_Type.GetBuffer(32), 32);<br />
Inst.m_Type.ReleaseBuffer();
If you know they are numbers, I'd use int s rather than CStrings and change the fscanf to:
fscanf(infile, "%d", &Inst.m_Type);
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
-- modified at 17:14 Wednesday 22nd February, 2006
|
|
|
|
|
Thanks,
Because my file is comma delimited with variable length fields, some with white space in them I used the approach below. Works great!
Buck
CString in_buffer;
char buffer[32];
FILE* infile;
char* config_file = "Config.txt";
infile = fopen(config_file, "r");
int end_of_file = 0;
CInstrument Inst;
// Here is where the input read from the Config.txt file and stored in the respective variables.
while (!end_of_file)
{
fscanf(infile, "%[^,]", &buffer);
in_buffer.Format("%s", &buffer);
Inst.m_Type = in_buffer;
fscanf(infile, "%[,]", &buffer);
fscanf(infile, "%[^,]", &buffer);
in_buffer.Format("%s", &buffer);
Inst.m_Name = in_buffer;
fscanf(infile, "%[,]", &buffer);
fscanf(infile, "%[^,]", &buffer);
in_buffer.Format("%s", &buffer);
Inst.m_GPIB = in_buffer;
fscanf(infile, "%[,]", &buffer);
fscanf(infile, "%[^\n]", &buffer);
in_buffer.Format("%s", &buffer);
Inst.m_Channels = in_buffer;
fscanf(infile, "%[\n]", &buffer);
m_ListInstruments.AddString(Inst.m_Name);
if (feof(infile))
end_of_file = 1;
}
Buck
|
|
|
|
|
Maybe you could save yourself some duplicate effort.
Could you replace this:
fscanf(infile, "%[,]", &buffer);<br />
fscanf(infile, "%[^\n]", &buffer);<br />
in_buffer.Format("%s", &buffer);<br />
Inst.m_Channels = in_buffer;
with this, for example:
fscanf(infile, "%[,]", &buffer);<br />
fscanf(infile, "%[^\n]", &buffer);<br />
Inst.m_Channels.Format("%s", &buffer);
That is one less string copy and memory adjustment.
You would not need or use the in_buffer at all.
People that start writing code immediately are programmers (or hackers), people that ask questions first are Software Engineers - Graham Shanks
|
|
|
|
|
Difficult to say without seeing the code... Can you post it?
|
|
|
|
|