|
Hi,
I have report template with report header and report body. In report body I need place two fields which will present large text but in fact I don't how big these fields should be to hold and present whole text. The best solution will be to set these fields to a minimal size in report templete and let them to widen to fit whole text. How can I cope with this problem??
Thanks a lot
Shark
|
|
|
|
|
I would in fact rather try to make them as big as possible. It they are placed based on each other, that is, one field should be located just after the other, this might not be possible however. In this case, you'll have to create a printer CDC , create a font matching the font you'll use for printing, and then loop all the texts, calling GetTextExtent for each string.
|
|
|
|
|
Thanks,
I can try make them as big as possible but what when the text is longer than one page. In the template editor I can widen these field to fit whole page, but reported text is longer that one page.How can I make it to be continued on several pages?
Thanks a lot
shark
|
|
|
|
|
Oooo, that is not possible without some trickery. What I would do would be to create a single column grid. Then I would split the text into lines, putting each line in the grid (the the report will then print the grid on as many pages as necessary).
How to split the text then? Well, you could write a function that gets a printer CDC and then uses GetTextExtent to walk the text and split it into lines that will fit in a single cell (that is, line).
|
|
|
|
|
The article looks very promising, to begin with.
I've downloaded all files, unpacked it and started playing. Started 'ReportCreator.exe', created a very simple report with a couple of fields. Then, started 'ReportGeneratorDemo.exe', loaded the report, created and saved in the first step. The message box said that the report had being loaded and it is ready to print. Calling up the print preview - shows three empty pages ... Then I realized, that re-opening the report(s) with the 'ReportCreator.exe', also brings up a clean white sheet. Nothing to see from the stuff that was put on it in the first step. Opening the .prt file in an editor however shows the stuff that was created:
(
paper:793,1122;
report_label ,697917,0,656250,2,208333,1,093750,Label,$app_name,0,Times New Roman,120,0,0,0,0,0,0,1,3381756,2,1243436;;
)
I'm using XP, Sp2. Any known issues with that?
Regards,
|
|
|
|
|
The problem is the delimiters. If you look at the first part of the saved label:
report_label ,697917
the value is a location - and it should be 0.697917 etc., in fact, the line should read
report_label .697917,0.656250,2.208333,1.093750,Label,$app_name,0,Times New Roman,120,0,0,0,0,0,0,1,3381756,2,1243436;;
Have you perhaps incorporated the editor in an app that sets the locale, thus using the comma instead of the decimal point?
|
|
|
|
|
Now that you brought that up, I think I know what's the reason for the failure: the local for the double format. Since I've run your binaries and did not changed anything on the file that had being created, I'm sure that this is the reason. I've had the very same problem a while ago in our company where a report (created by a application written in cpp) that contained some double number could not be imported into Excel at a customer. I turned out that to be the problem I've described above, the delimiter in the doubles where wrong.
Regards
|
|
|
|
|
What is embarassing is that me, being Swedish, actually uses the decimal comma rather than the point
|
|
|
|
|
|
When clicking on an object (label or field) in the DiagramEditor the object may move slightly. I assume this is because the code catches the left button down and the small inadvertent mouse move before it sees the left button up.
Most similar apps do not have the same problem. It would be nice if the DiagramEditor could discern between single clicks and true click and drag events.
Anyone have a work around for this?
|
|
|
|
|
Your analysis is indeed true. This might - for example - be fixed by not starting to register mouse movement until a certain (small) time has elapsed, or perhaps by discarding movements under a given amount of pixels. It is slightly difficult, however, to find a good general solution - note that the underlying vector editor is a general class.
|
|
|
|
|
Hi Again,and have good time
dear johan
as i read your docs about R.G. you had used inch for internal measurments.but i notice this is only when you archive them.
the problem arises when CUnitConversion is not yet initialized and s_resolution is zero or something else other than load time.
you can reproduce this by adding
BOOL CReportCreatorApp::InitInstance()<br />
{<br />
......<br />
ParseCommandLine(cmdInfo);<br />
<br />
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;<br />
if (!ProcessShellCommand(cmdInfo))<br />
return FALSE;<br />
......<br />
}
and try to load a saved report.
this may be simplly solved by initializing CUnitConversion but i think this valuable code must be independent of Application and it is better CDiagramEntityContainer be aware of resulotion used for it's objects and have correction methods for resolution changs.
REGARDS Peiman
|
|
|
|
|
Thanks for the suggestion! Another idea that comes to mind is to let CUnitConversion self-initialize. I'm getting slightly desperate when it comes to updating the article, though
|
|
|
|
|
Hello there,
I see some questions on the forum regarding this subject, I have solved it for myself through the following function. If you call this function like this
int PreviousOrientation = SetDefaultPrinterOrientation(DMORIENT_LANDSCAPE);
It will switch printing to Landscape, and you can use the returned value to set it back to whatever it was set before the call, by passing that value and calling it again.
Hope someone can find this useful
Cheers
Alex
#include "winspool.h"
int SetDefaultPrinterOrientation(short dmOrientation)
{
HANDLE hPrinter = NULL;
DWORD dwNeeded = 0;
PRINTER_INFO_2 *pi2 = NULL;
DEVMODE *pDevMode = NULL;
PRINTER_DEFAULTS pd;
BOOL bFlag;
LONG lFlag;
LPTSTR pPrinterName = NULL;
DWORD size;
GetDefaultPrinter(NULL, &size);
TCHAR* buffer = new TCHAR[size];
if(GetDefaultPrinter(buffer, &size))
pPrinterName = buffer;
else
{
if(buffer != NULL)
delete buffer;
return 0;
}
// Open printer handle (on Windows NT, you need full-access because you
// will eventually use SetPrinter)...
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bFlag = OpenPrinter(pPrinterName, &hPrinter, &pd);
if (!bFlag || (hPrinter == NULL))
{
if(buffer != NULL)
delete buffer;
return 0;
}
// The first GetPrinter tells you how big the buffer should be in
// order to hold all of PRINTER_INFO_2. Note that this should fail with
// ERROR_INSUFFICIENT_BUFFER. If GetPrinter fails for any other reason
// or dwNeeded isn't set for some reason, then there is a problem...
SetLastError(0);
bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
if ((!bFlag) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
// Allocate enough space for PRINTER_INFO_2...
pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (pi2 == NULL)
{
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
// The second GetPrinter fills in all the current settings, so all you
// need to do is modify what you're interested in...
bFlag = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
// If GetPrinter didn't fill in the DEVMODE, try to get it by calling DocumentProperties...
if (pi2->pDevMode == NULL)
{
dwNeeded = DocumentProperties(NULL, hPrinter,pPrinterName,NULL, NULL, 0);
if (dwNeeded <= 0)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
if (pDevMode == NULL)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
lFlag = DocumentProperties(NULL, hPrinter,pPrinterName, pDevMode, NULL,DM_OUT_BUFFER);
if (lFlag != IDOK || pDevMode == NULL)
{
GlobalFree(pDevMode);
GlobalFree(pi2);
ClosePrinter(hPrinter);
if(buffer != NULL)
delete buffer;
return 0;
}
pi2->pDevMode = pDevMode;
}
// Driver is reporting that it doesn't support this change...
if (!(pi2->pDevMode->dmFields & DM_ORIENTATION))
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
// Specify exactly what we are attempting to change...
pi2->pDevMode->dmFields = DM_ORIENTATION;
// Make note of the current Orientation setting
// If the functions works, return it to the calling program
// So that, the application can set it back to whatever
// it used to be before the call
int OriginalOrientation = pi2->pDevMode->dmOrientation;
// Now, change it to whatever was requested by the calling application
pi2->pDevMode->dmOrientation = dmOrientation;
// Do not attempt to set security descriptor...
pi2->pSecurityDescriptor = NULL;
// Make sure the driver-dependent part of devmode is updated...
lFlag = DocumentProperties(NULL, hPrinter, pPrinterName, pi2->pDevMode, pi2->pDevMode, DM_IN_BUFFER | DM_OUT_BUFFER);
if (lFlag != IDOK)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
// Update printer information...
bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (!bFlag) // The driver doesn't support, or it is unable to make the change...
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return 0;
}
// Tell other apps that there was a change...
SendMessageTimeout(HWND_BROADCAST, WM_DEVMODECHANGE, 0L,(LPARAM)(LPCSTR)pPrinterName, SMTO_NORMAL, 1000, NULL);
// Clean up...
if (pi2)
GlobalFree(pi2);
if (hPrinter)
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
if(buffer != NULL)
delete buffer;
return OriginalOrientation;
}
|
|
|
|
|
Thanks for this useful addition. Personally, I think the above should be made a mini-article of its own.
|
|
|
|
|
Hi Johan
Thanks for your feedback, I just uploaded something to the site, including one extra function to set up paper type / size
Cheers
Alex
|
|
|
|
|
Hi Again
if Ruler measurment is Pixel
the above Method makes HorzRuler & VertRuler to fall in endless loop because of negative segment and application crashs !
the quick workaround could be this that makes Rulers stable if
m_zoomMin is not less than 0.5
<br />
SetZoom( max(min( zoomx, zoomy ),m_zoomMin) );<br />
<big>OR BETTER SOLUTION</big><br />
void CReportEditor::SetZoom( double zoom )<br />
{ <br />
int z = static_cast< int >( zoom * 100.0 );<br />
CDiagramEditor::SetZoom( zoom );<br />
GetParent()->SendMessage( UWM_ZOOM, z );<br />
}<br />
<big>change to</big><br />
void CReportEditor::SetZoom( double zoom )<br />
{ <br />
CDiagramEditor::SetZoom( zoom );<br />
int z = static_cast< int >( CDiagramEditor::GetZoom() * 100.0 );<br />
GetParent()->SendMessage( UWM_ZOOM, z );<br />
}<br />
but i think u should also revise the DrawScale loop of Rulers.
REGARDS PEIMAN
i really love this code
|
|
|
|
|
Thanks a lot for the feedback!
The latter method would indeed be prefered - but I'll also do something to the UWM_ZOOM -handler.
|
|
|
|
|
Hi Dear Johan thanks for ur Nice Work .
BTW
The thickness for those items are not handled while zoom is changed and they were displayed with fixed thickness.
REGARDS PEIMAN
|
|
|
|
|
Thanks for the feedback!
If the thickness is not changed, and you've set an explicit width, it's a bug, I must admit.
|
|
|
|
|
Hi
just because of topic relation .
setting the value of thickness in thier respective property dialogs had been omitted except for Line.:->
REGARDS Peiman
|
|
|
|
|
How can me makes the images as the Reports background?
crystalice
|
|
|
|
|
I might be missing something here? The answer would seem to be "put an image field in the report and the other fields above it" - as this seems a bit simple, perhaps I'm misunderstanding you?
|
|
|
|
|
Hi there!
I have a template with a couple of fields at the top (combined page head/report head), below that a indefinite amount of data, and below that a couple of fields which sums the data in the grid (side foot/report foot). How do I get the size/height/number of rows of the grid to be minimal? I do not want the fields under the grid at the bottom of the page - they shold "follow" the last row of the grid.
* When I make three templates (one for the head, one for the data and one for the foot), it will be page brekings between the templates which I don't want.
* When I put all the three templates in one template, I will not get the sum exactly under the last row in the grid.
How do I solve the problem? All solutions and hints are very appreciated!
Johan - mycket bra verktyg förövrigt!
/Felix
|
|
|
|
|
Felix,
This is not supported functionality supported, but indeed already suggested. Given that I have a todo-list long as an arm and a leg, I have no idea when I'll get time to go through it, though
The functionality you need is not trivial to add, although it will sooner or later be implemented. In wait for that, you might perhaps try to arrange the grid in such a way that you can reuse cells for the sums? With gridlines turned of, perhaps using separators, you might get an acceptable layout anyway?
|
|
|
|
|