How can I print text fields at the right coordinates? - delphi

I don't have any background in programming and this is my first shot. I wrote a Delphi program that is supposed to print on a result sheet. I work in an institute and we have to establish hundreds of result sheets every 2 months. It's really difficult to do that and different handwriting is also an important issue. I have this code:
if PrintDialog.Execute() then
begin
with MyPrinter do
begin
MyPrinter.BeginDoc();//Start Printing
//Prints First Name
MyPrinter.Canvas.TextOut(FirstNameX,FirstNameY,EditFirstName.Text);
//Prints Last Name
MyPrinter.Canvas.TextOut(LastNameX,LastNameY,EditLastName.Text);
//Prints Level
MyPrinter.Canvas.TextOut(LevelX,LevelY,EditLevel.Text);
//Prints Date
MyPrinter.Canvas.TextOut(DateX,DateY,MEditDate.Text);
//Prints Student Number
MyPrinter.Canvas.TextOut(StdNumX,StdNumY,EditStdnumber.Text);
....
MyPrinter.EndDoc();//End Printing
end;
end;
I can't get the right coordinates to print properly. Am I missing something? How can I set the right coordinates? You know TPrinter uses pixels to get the coordinates but papers are measured in inches or centimeters.
I'm really confused. I appreciate any help.

#Milad I recommend you use a report component like Quick Report (comes with the oldies versions of delphi and is very easy to use) or FreeReport (it's free) to make your task easier.
for more info check theses links
QuickReports Tutorial
QuickReports Documentation, Knowledge Base and FAQ
if you want to print directly from delphi without components here I leave a couple of links that can help.
Printing Directly from Delphi
Delphi - Printing via the TPrinter Canvas

While using a reporting tool is a good idea, if you really do want to do it yourself, you can. I do this for printing to custom paper in our licensing application. The key is to know the size of your paper, and work it out from that using the printer PageHeight and PageWidth properties. For A4 paper I chose to use 297mm by 210mm, and from that I was able to calculate where I wanted things to be. The calculation is done thus:
nStartPos := 210-141;
nUserColX := muldiv(localPrinter.PageWidth, 187, 297);
nUserColY := muldiv(localPrinter.PageHeight, nStartPos, 210);
The nStartPos variable is done to start on a particular place, and then nUserColY is used to move down a line at a time as here:
nUserColY := nUserColY - localPrinter.canvas.font.height - (localPrinter.canvas.font.height div 8);
This then allows more than one line at a time to fit nicely.
This is not complete, but should be a good start for custom printing.

Related

How to set paper size to unlimited in delphi 7

I'm developing a cashier application using Delphi 7 and QuickReport 3.0.9.
The problem is the printing module is limited to the size of the component length in the form, so when the user prints a very long list of item, some of the items will get cut off. The printer is a special printer for cashiers (I don't know the correct name for this printer) that uses a roll of paper, so the printout length should be unlimited.
How do I set the printout length to unlimited? I already emptied the QuickRep1 - Page - Length property but it's still cut off at some point.
Unfortunately you cannot do it with QuickReport v3.0.9.
Support for continuous paper has been introduced with QuickReport v5 update:
Continuous paper. A new property of TPage, Continuous adds support for printing from rolls
When you set the Continuous property to true, the report should not contain any newpage commands.

Getting Delphi to print a two page document onto one A4 with two coulmns

I need help setting up printing in Delphi XE3 / RAD Studio XE3. I have created a form intended to be used on a dot matrix printer so the normal .print method does not work as it prints the background of the form. All information is being written into the RichEdit box but spans over two pages. I need that information to be printed onto one A4 page with two columns (half of the information on the left and the rest of the information on the right) on one page
The problem I am having with tabs is, since most of the information will be entered by the user, I will not know how many tabs to use to get the center of the page and thus have alignment problems.
You don't need to send EM_LINEINDEX messages to display text in two columns.
Here's an example of added tab-separated columns to a TRichEdit. It's clearly not using the text you're trying to output, because I wouldn't likely have the registry entries you're trying to access and therefore couldn't test before posting. It should get you started (but see my note below before doing so).
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 50 do
RichEdit1.Lines.Add(Format('%d'#9'This is line %d', [i, i]));
end;
The simplest way to print the TRichEdit (if all of the content will fit on a single page) is to simply call TRichEdit.Print.
With that being said, creating a visual control that you'll never display is usually the wrong approach. All versions of Delphi that have ever been released come with some sort of reporting engine (Quick Reports, Rave Reports, Fast Reports) that are designed to easily create printed output. XE3 comes with Fast Reports, which would make very short work of this type of report and would allow you to control output very accurately. If you're going to be working with Delphi, it's worth becoming familiar with its reporting components; they'll save you lots of work, code and frustration in a very short time frame.

How to program a small program?

I would like to program productive and keep my FileSize very small.
However I would like to know a few tips how do accomplish that.
For example what is better for a small FileSize:
Either:
if .... = '1' then begin
...
end;
or:
if ..... = inttostr(1) then begin
...
end;
or:
if .... = inttostr($0001) then begin
...
end;
or:
case of intvar
1: ...
2: ...
end;
Then there is something that I tried and I was surprised.
I made another Unit in my project that stores Strings as constants and then I use the constant vars to replace the strings in my project. For some reason this raises my FileSize although I replace double used Strings as a var now.
Also is it better to store stuff in vars than put them directly into the code?!
For example:
Function1(param1, param2, param3); // this code is used about 20 times in my project
or is it better if I:
Avar = Function1 (param1,param2,param3); // Store this once in a var and then replace it
And what about:
if ... = TRUE
or:
if ....
Same as:
if .... = FALSE
or:
if not(...)...
Any other tips to program productive for a smaller FileSize?
Thanks in advance.
I use Delphi7
I'm sorry to be blunt, but you are putting the cart before the horse.
If you really want to know how to make your executable smaller without already knowing what differences will result from your code variations in your given examples, you should just stop right now and read/learn/practice until you know more about the language and the compiler.
Then you'll understand that your question makes little sense per se, as you can already see by all the pertinent comments you got.
the exact same source code can result in vastly different executables and different source code can result in the same executable, depending on the compiler options/optimizations
if your main goal is to micro-manage/control the generated exe, program directly in assembler.
if you want to know what is generated by the compiler, learn how to use the CPU View.
program for correctness first, then readability/maintainability
only then, if needed (implies using correct metrics/tools), you can optimize for speed, memory usage or file size (probably the least useful/needed)
Long time ago, i tried to make a program as small as possible, because it had to fit onto a floppy disk (yes i know i'm a dinosaur). This Splitter tool was written in Delphi and is about 50KB in size.
To get it this small, it was necessary to do without a lot of Delphi's units (especially the Forms unit and all units with references to it). The only way, was to use the Windows-API directly for the GUI, and i can't think of a reason to do this nowadays, but out of interest.
As soon as you use the VCL, the exe size will grow much more, than all micro optimizations in your code together can reduce it.

How can I increase the size of the string that an external debugger visualizer can display?

I am once again writing an external debugger visualizer, and am running into a wall. There appears to be a limit to the size of the string that the debugger visualizer can return.
The TStrings debugger visualizer that shipped with Delphi 2010 had a limit of 4K. In a response to a question posted on Embarcadero's newsgroups, Ewe Schuster replied that "You can increase the buffer a little bit, but AFAIR the actual limitation is in IOTAThread.Evaluate with a limit of about 12k chars."
My debugger visualizer is based on the code of the TStrings debugger visualizer, and I can see that the implementation of the TFrame's Evaluate method includes the following declaration of ResultStr, which is used to return the string returned from the IOTAThread.Evaluate call:
ResultStr: array[0..4095] of Char;
I had hoped that increasing the size of this buffer would help, but no luck.
What can I do, if anything, to increase the size of the string that my external debugger visualizer can display?
I had the same limited patience for that limit...
So I made a debug visualizer that work around the limitation mostly by creating a MemoryStream in the debugged process to hold the string result of the Expression, then use something like
CurProcess.ReadProcessMemory(StrToInt(SrcMemoryAddr), DstMemStream.Size, DstMemStream.Memory^);
to copy it into a visualizer's MemoryStream. Then you can do whatever you want to display it (for instance formatting it for human reading if it's an XML string like a CLientDataSet.XMLData).
There are few tricks depending if the Expression is a const string, a var, or needs evaluation etc...
My FGStringVisualizer is not 100% satisfying, which is why I haven't published it yet on my blog, but as it does 99% of what I need, I didn't take the time to clean it a bit and publish it even "as-is". But if there is a need I can certainly do it with all needed disclaimers...
Update:
It's the same idea that I used for my FGStringListVisualizer that I presented at the last DelphiLive. By the way, this one also might be worth putting on my blog as I made a few improvements since.

Recommendations for plotting (chart) component?

I am searching for a widget or control to plot a time-series of data. Basically plot(x,y) where x and y are Nx1 vectors. I am looking but haven't found much and any suggestions would be great! Thanks.
Use TeeChart, supplied with Delphi. Good for time series and also real time graphs.
I prefer TJvChart from the Jedi VCL library, but then I wrote the TJvChart, or most of it anyways. The reason I recommend it is that it's free, but it has some limitations, including a lack of proper zoom-in and zoom-out capability.
I don't like to use any component in my apps that does not include source code, and generally caution against closed source component use in any serious project, so plan to buy the TeeChart source code if you'll need to use the component. I'm not anti Tee-Chart though; If you choose to use it in a commercial project, go ahead it's great too. Just be aware that it's really 100% worth buying the source for anything you really want to use in a serious way.
Quick start:
1. Download and install JVCL.
2. Open included JvChart demos.
Stackoverflow style tutorial:
1. drop TJvChart on a form.
2. write this code:
JvChart1.Options.PenCount := 1;
JvChart1.Data.ValueCount := 3;
// set values for [penIndex=0, valueIndex=0..2 ]
JvChart1.Data.Value[0, 1] := 1;
JvChart1.Data.Value[0, 2] := 3;
JvChart1.Data.Value[0, 3] := 5;
JvChart1.PlotGraph;

Resources