|
[edit]Please ignore this, see responses below[/edit]
Using #pragma once still forces the compiler to at least reopen the header file. If you want to prevent that as well you have to place the guards outside the header file, around every inclusion, such as this:
#define MY_GUARD_A_H
class A {
};
#ifndef MY_GUARD_A_H
#include "A.h"
#endif
I've done it like that in a project once, some 20+ years ago, but it was a hell to maintain. It did help a lot though, as it was really a huge project, and computers (and specifically file system calls) weren't all that fast at the time.
modified on Tuesday, February 1, 2011 5:55 AM
|
|
|
|
|
I don't know for sure, but I see no reason that Niklas Lindquist's comment would be wrong.
When the preprocessor sees the #pragma once in a file, it should mark that file as having been included and that it does not need to be included again.
This list would need to be kept in order for the directive to work, so there is no reason that it should need to re-open the same file to realise this.
|
|
|
|
|
I am sorry, I've just looked up the description of #pragma and according to what it says you, and Niclas, are indeed correct.
I always thought the preprocessor would always have to resolve #include statements until coming to a #pragma , but when I think about it, it's trivial to keep a list of files that have #prgama once specified. My bad for never looking for the exact definition of this feature...
|
|
|
|
|
Don't feel bad, I never knew it until Niclas said it.
And even then, I only assumed he was right because it would be rather silly to not do it that way.
|
|
|
|
|
Andrew Brock wrote: it would be rather silly to not do it that way
indeed it would.
|
|
|
|
|
No worries
|
|
|
|
|
I would like to point out that even if you do not #include the same header multiple times within the same file, the multiple inclusion issue still exists: the reason is that you might indirectly include a header multiple times through #include statements in header files that you include, for example:
class A {
};
#include "A.h"
class B : public A {
};
#include "B.h"
#include "A.h"
The first statement in B.cpp includes B.h, which in turn includes A.h. B.cpp then continues to include A.h again, which will cause a compiler error.
|
|
|
|
|
this[^] would help you. I prefer you to go through the "Conditional inclusions (#ifdef, #ifndef, #if, #endif, #else and #elif)" section of the article and 'Avoiding Including Files Multiple Times (idempotency)' section of this [^]link.
|
|
|
|
|
Hi there,
I am developing a custom print dialog and page setup for my Win32 program. Since the code is legacy, I can't take much advantage from MFC view/doc architecture. As a result, I wrote a printing code completely from scratch.
I setup CPrintInfo, instantiate my custom print dialog box and hook this dialog box to the CPrintInfo I just created. When my custom print dialog is up, I have a radio button to let a user toggles the page orientation. For some reasons, I couldn't modify the current DEVMODE at the run-time. As a result, every page I print will end up as a portrait.
<b>Here is the code I have:</b>
void PrintSomething(CWnd* currentWnd)
{
// Create CPrintInfo
CPrintInfo* pPrintInfo = new CPrintInfo;
SetupPrintInfo(pPrintInfo); // simply setup some member variables of CPrintInfo
// Create a custom print dialog and use this dialog box during instead of the default CPrintDialog
CustomPrintDlg* pCustomPrtDlg = new CustomPrintDlg(FALSE, PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS
| PD_HIDEPRINTTOFILE | PD_NOSELECTION, pPrintInfo, currentWnd);
SetupPrintDialog(pPrintInfo,pCustomPrtDlg);
if ( AfxGetApp()->DoPrintDialog(pCustomPrtDlg) == IDOK ) {
... // proceed a print loop
}
}
void SetupPrintDialog(CPrintInfo* pPrintInfo,CustomPrintDlg* pCustomPrtDlg)
{
delete pInfo->m_pPD;
pInfo->m_pPD = pCustomPrtDlg;
pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
pInfo->m_pPD->m_pd.lpPrintTemplateName = MAKEINTRESOURCE(IDD_CUSTOM_PRTDLG);
// Set the Flags of the PRINTDLG structure as shown, else the
// changes will have no effect.
pInfo>m_pPD->m_pd.Flags |= PD_ENABLEPRINTTEMPLATE;
// Set the page range.
pInfo>m_pPD->m_pd.nMinPage = 1; // one based page numbers.
pInfo>m_pPD->m_pd.nMaxPage = 0xffff; // how many pages is unknown.
}
When a user toggles the radio button to Landscape, this function will be invoked:
void CustomPrintDlg::OnLandscapeChecked()
{
// set the current Devmode to landscape
LPDEVMODE pDevMode = GetDevMode();
GlobalUnlock(pDevMode);
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
}
class CustomPrintDlg: public CPrintDialog {
... // just override some methods from CPrintDialog
};
Even if I manually set pDevMode->dmOrientation to DMORIENT_LANDSCAPE when the dialog is up, the printing result is still ended up in Portrait. I am really not sure why this is happening. Please help.
Thank you in advance for any help.
Un
Un
-- Modified Thursday, February 3, 2011 10:30 PM
|
|
|
|
|
Shouldn't the call to GlobalUnlock be after the line trying to set the operation?
void CustomPrintDlg::OnLandscapeChecked()
{
LPDEVMODE pDevMode = GetDevMode();
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
GlobalUnlock(pDevMode);
}
If you vote me down, my score will only get lower
|
|
|
|
|
Thanks for pointing that out. It turns out that I need to get a pointer to the DevMode using GlobalUnlock before I modify the DevMode.
Here is the code I have and it works:
void CustomPrintDlg::OnLandscapeChecked()
{
// set the current Devmode to landscape
LPDEVMODE pDevMode = GetDevMode();
GlobalLock(pDevMode);
pDevMode->dmOrientation = DMORIENT_LANDSCAPE;
GlobalUnlock(pDevMode)
}
Un
|
|
|
|
|
I just cant get this, how would you, for example, return, lets say, a (database) table from a function?
In C (no c++ stuff). For example, we got a table like:
row one
row two
2 rows with 2 columns, 2x2:
wchar_t *array[2][2]
{
{L"row", L"one"},
{L"row", L"two"}
};
But how to create things dynamically? And we dont know how many rows are there, nor how many columns.
How to allocate mem for this, and then do something like: (thats wrong and lame an i know it is pathetic)
array = malloc(initial size/* which is: 1 row and 1 column */)
getting_a_row, ok, it has 2 columns, allocating mem for 1 row and 2 columns
proceeding... we got next row! so now we got 2 rows and 2 columns, allocating mem for next row with 2 columns
and then something even more lame:
wcscpy(rows[0][0], L"row"); wcscpy(rows[0][1], L"one");
wcscpy(rows[1][0], L"row"); wcscpy(rows[1][1], L"two");
thanks
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
If the structure is know, then you can simply make an array of structures.
typedef struct {
wchar_t szCol1[4];
whcar_t szCol2[4];
} DatabaseRow;
DatabaseRow drTable[2] = {
{ L"row", L"one" },
{ L"row", L"two" }
};
Most databases will have a pre-allocated string, with a maximum length (generally not including the NULL terminating character), you would make the size of the char array the length of the field it represents +1. If there is no maximum length, then you will need to use a string pointer with dynamically allocated memory by using malloc
If the structure is unknown you could use something like
typedef struct {
DWORD nFieldLen;
BYTE pFieldData[];
} DatabaseField;
Your table row will then need to contain a pointer to 1 of these structures for each column
typedef struct {
DWORD nColumns;
DatabaseField *pColumns[];
} DatabaseRow;
int nColumns = 3;
DatabaseRow *pRow = (DatabaseRow *)malloc(sizeof(DatabaseRow) + sizeof(DatabaseField) * nColumns);
The same principal can be used for allocating each field and the entire table, all you need is the number of rows, columns and the size of each column.
You will then need to cast the data in the column to the correct type.
Note that as far as I know all SQL implementations return everything as text, it is then up to you to interpret these as a number, date, binary data (from hex), ...
|
|
|
|
|
Alright! Thanks very much. I have totally forgot about good old structures and pointers to them. Will play with it for a little bit.
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
OK, here is how we do it: (once again, Andrew, you rock!)
typedef struct _DatabaseField
{
DWORD nFieldLen;
wchar_t pFieldData[];
} DatabaseField;
typedef struct _DatabaseRowEx
{
DWORD nColumns;
DatabaseField *pColumns[];
} DatabaseRowEx;
int nColumns = 3, x = 0, rowz = 1;
wchar_t *row1elems[] = {L"aaa", L"bbb", L"ccc"};
wchar_t *row2elems[] = {L"111", L"222", L"333"};
DatabaseRowEx *pRow = (DatabaseRowEx *)malloc(sizeof(DatabaseRowEx) +
sizeof(DatabaseField) * nColumns * rowz);
wprintf(L"Row 1: ");
for(x = 0; x < nColumns; x++)
{
pRow[0].pColumns[x] = (DatabaseField *)malloc(sizeof(wchar_t *) *
wcslen(row1elems[x]) + 1);
wcscpy((wchar_t *)pRow[0].pColumns[x], row1elems[x]);
wprintf(L" [ %s ] ", pRow[0].pColumns[x]);
}
wprintf(L"\r\n");
rowz++;
pRow = (DatabaseRowEx *)realloc(pRow, sizeof(DatabaseRowEx) +
sizeof(DatabaseField) * nColumns * rowz);
wprintf(L"Row 2: ");
for(x = 0; x < nColumns; x++)
{
pRow[1].pColumns[x] = (DatabaseField *)malloc(sizeof(wchar_t *) *
wcslen(row2elems[x]) + 1);
wcscpy((wchar_t *)pRow[1].pColumns[x], row2elems[x]);
wprintf(L" [ %s ] ", pRow[1].pColumns[x]);
}
wprintf(L"\r\n");
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
An abrupt way of doing this is creating a
std::vector<std::vector<std::string> > and create some functions to properly arrange its sizing taking two parameters (rows and cols).
something like:
#include <vector>
#include <string>
class text_table:
public std::vector<std::vector<std::wstring > >
{
typedef std::vector<std::vector<std::wstring > > super;
public:
typedef std::wstring string_t;
void resize(size_t rows, size_t colums)
{
super::resize(rows);
for(size_t i=0; i<rows; ++i)
super::at(i).resize(cols);
}
const string_t& at(size_t rew, size_t col) const
{ return super::at(row).at(col); }
string_t& at(size_t rew, size_t col)
{ return super::at(row).at(col); }
};
If you need to return it from a function, probably a std::auto_ptr may avoid the copy-on return of a relatively huge structure.
Something like:
#include <memory>
#include "texttable.h"
std::auto_ptr<text_table> create_table( ... )
{
std::auto_ptr<text_table> p(new text_table);
p->resize(...);
.... ....
return p;
}
If you want better isolation, you can elaborate by encapsulating (rather then inheriting) the
std::vector<std::vector<std::wstring> > as a private member
and write a brand new interface for all the tex_table operation you may suppose to need.
In that case you can also avoid the use of auto_ptr if you store a pointer (rather than the structure itself) and manage copy and assignment by handling a reference count, and create an effective copy of the data only if the data are shared and needed to be modified.
There are lot of improvements possible!
2 bugs found.
> recompile ...
65534 bugs found.
modified on Tuesday, February 1, 2011 2:58 AM
|
|
|
|
|
Ok, thanks. Although thats not actually what i needed here, but gives some insight too.
Well, i need to return this from function from C dll to c/c++/c# apps, so good old C is the only way :X
011011010110000101100011011010000110100101101110
0110010101110011
|
|
|
|
|
Hey all, hope everyone had a great weekend.
I have some code where I am passing a string array and some numbers and want to reconcile the two as far as a lookup table. When I want to compare a value in an array to a value passed to the function it wants arg1 to be boolean, but I am not sure the proper syntax. can anyone give me an idea of what I am doing wrong? Also, I am not sure the code will work as written anyway, but this is the only error popping up so far.
double __stdcall HEI_F2(string &arg1, int &arg2)
{
int tp;
int bg;
int counter, typ, bwg, b;
string vl_reg1[16] = {"70-30 Cu-Ni", "90-10 Cu-Ni", "Admiralty Metal", "Aluminum Brass", "Aluminum Bronze", "Arsenical Copper", "Cold-Rolled Low Carbon Steel", "Copper Iron 194 (Olin 194)", "Titanium Grades 1 & 2", "304 SS", "316/317 SS", "N08367 (AL6XN)", "S43035 (TP439)", "S44660 (Sea-Cure)", "S44735 (AL29-4C)"};
string a;
int vl_reg2[10] = {12, 14, 16, 18, 20, 22, 23, 24, 25};
double vl_reg12[16] = {0.71, 0.8, 0.93, 0.92, 0.89, 0.98, 0.81, 1, 0.64, 0.54, 0.53, 0.48, 0.63, 0.58, 0.58};
double vl_reg14[16] = {0.78, 0.85, 0.96, 0.95, 0.93, 1, 0.86, 1.01, 0.71, 0.62, 0.61, 0.56, 0.71, 0.66, 0.66};
double vl_reg16[16] = {0.83, 0.89, 0.98, 0.97, 0.96, 1.01, 0.9, 1.02, 0.77, 0.69, 0.67, 0.63, 0.77, 0.72, 0.72};
double vl_reg18[16] = {0.88, 0.93, 1, 0.99, 0.98, 1.02, 0.94, 1.03, 0.83, 0.75, 0.74, 0.7, 0.82, 0.79, 0.79};
double vl_reg20[16] = {0.92, 0.96, 1.01, 1.01, 1, 1.03, 0.97, 1.03, 0.89, 0.82, 0.81, 0.78, 0.88, 0.85, 0.85};
double vl_reg22[16] = {0.95, 0.98, 1.02, 1.02, 1.01, 1.03, 0.98, 1.04, 0.91, 0.86, 0.85, 0.82, 0.91, 0.89, 0.89};
double vl_reg23[16] = {0.96, 0.99, 1.02, 1.02, 1.01, 1.04, 0.99, 1.04, 0.93, 0.88, 0.87, 0.84, 0.92, 0.9, 0.9};
double vl_reg24[16] = {0.97, 0.99, 1.03, 1.02, 1.02, 1.04, 1, 1.04, 0.94, 0.9, 0.89, 0.86, 0.94, 0.92, 0.92};
double vl_reg25[16] = {0.97, 1, 1.03, 1.03, 1.02, 1.04, 1, 1.04, 0.95, 0.91, 0.9, 0.88, 0.95, 0.93, 0.93};
string vl_reg3[16] = {"vl_reg12", "vl_reg14", "vl_reg16", "vl_reg18", "vl_reg20", "vl_reg22", "vl_reg23", "vl_reg24", "vl_reg25"};
counter = 0;
do{
a = vl_reg1[counter];
if (arg1 = a)
{
tp = counter;
}
counter = counter + 1;
}while (counter <= 16);
counter = 0;
do{
b = vl_reg2[counter];
if (tp = b)
{
bg = counter;
}
counter = counter + 1;
}while (counter <= 10);
return vl_reg3[bg][tp];
}
|
|
|
|
|
jharn wrote: ...but this is the only error popping up so far.
What error?
jharn wrote: if (arg1 = a)
Do not confuse == with = .
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Sorry, I wasn't clear....
in the part where I compare if (arg1 = a) it tells me expression must have a bool type.
|
|
|
|
|
jharn wrote: in the part where I compare if (arg1 = a) it tells me expression must have a bool type.
Right, you are confusing == with = .
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
Hi, I tried arg1==a, now it says that no operator "==" matches these operands.
|
|
|
|
|
I think you need to use the 'compare' method. It returns 0 if they're equal, a positive int the string is greater, or a negative int if the string is less. Therefore:
if (arg1.compare(a) == 0)
|
|
|
|
|
Is that not an AND function? ==
I guess I am confused.....
|
|
|
|
|
jharn wrote: Is that not an AND function? ==
Uh, no. That is the equality operator.
The two AND operators are bitwise (& ) and logical (&& ).
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|