GIDForums  

Go Back   GIDForums > Computer Programming Forums > .NET Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 31-Mar-2005, 13:51
toddm123 toddm123 is offline
New Member
 
Join Date: Feb 2005
Posts: 9
toddm123 is on a distinguished road

Printing problems--->ARG!


Hi All,

I've got a vc++.net project that when needed prints from a listview form. Here's an example I found on MSDN:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdrawingprintingprintdocumentclassprintpagetopic.asp

This is a an example of how to print one line per row starting at the left most of the page for the xaxis. Like I said before, I have a listview with multiple rows AND columns. Anyways, I got the columns printing where they should under each column. Great.

Then I had to implement code that would print out the columns and rows etc... properly even if the user had completely covered the values in the listview. I had to create my own ratio of screen font to print font to figure out how to do that. I set up column minimum limits and have a function that removes charaters until they fit under the appropriate columns WITHOUT overlapping. Here's an example of what I mean:

Normal print:
Vendor------PartD---Description
Johnny_Boy-123456-wrench

User overlaps the listview fields completely and prints:
Vendor-Part-Description
Johnny_1234wrench

Anyways my ratio seemed ok but now I have to right align some fields (ARRG!). Here's my code so far:

CPP / C++ / C Code:
private: System::Void printPickList_PrintPage(System::Object *  sender, System::Drawing::Printing::PrintPageEventArgs *  e)
		 {
             float linesPerPage = 0;
			 float xPos=0;
             float yPos = 0;
             int count = 2;
             float leftMargin = (float)e->MarginBounds.Left;
             float topMargin = (float)e->MarginBounds.Top;
             ListViewItem* line;
			 bool moreLines=false;
			 String* description = new String("Description");
			 String* vendor = new String("Vendor");
			 String* substitute = new String("");
			 String* part = new String("Part");
			 String* qty = new String("Qty.");
			 String* bin = new String("Bin");
			 String* onhand = new String("On Hand");
			 String* onorder = new String("On Order");
			 String* price = new String("Price");
			 String* cost = new String("Cost");
			 
			 //Ratio created to support the sizing difference between
			 //the print width and the text width.
			 double ratio = 7.15152;

			 //Dealing with the xaxis of text
			 double value = 0.0;

             // Calculate the number of lines per page.
             linesPerPage = e->MarginBounds.Height / printFont->GetHeight(e->Graphics);

			if (pfwSettings->HeaderPrintOut->Length>0) {
				e->Graphics->DrawString(pfwSettings->HeaderPrintOut, printUnderlineFont, Brushes::Black, leftMargin, topMargin , new StringFormat());
				String *delim = "\n";
				String *split[] = pfwSettings->HeaderPrintOut->Split(delim->ToCharArray());
				count+=split->Length;
			} else {
				e->Graphics->DrawString(pfwSettings->WindowTitle, printUnderlineFont, Brushes::Black, leftMargin, topMargin , new StringFormat());
			}

			yPos = topMargin + (count * printFont->GetHeight(e->Graphics));
			xPos = 0;
			if (!pfwSettings->Print_HideVendor) {
				e->Graphics->DrawString(vendor, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
				xPos += convertViewWidthToPrintWidth(clmn_Vendor->Width, vendor->Length, ratio,0);
			}

			if (!pfwSettings->Print_HideSubstitute) {
				e->Graphics->DrawString(substitute, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
				xPos += convertViewWidthToPrintWidth(clmn_Subs->Width,substitute->Length, ratio,0);
			}
			
			e->Graphics->DrawString(part, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
			xPos += convertViewWidthToPrintWidth(clmn_Part->Width, part->Length, ratio,1);

			if (!pfwSettings->Print_HideDescription) {
				e->Graphics->DrawString(description, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
				xPos += convertViewWidthToPrintWidth(clmn_Description->Width, description->Length, ratio,0);
			}

            e->Graphics->DrawString(qty, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
			xPos += convertViewWidthToPrintWidth(clmn_Qty->Width, qty->Length, ratio,2);

			if (!pfwSettings->Print_HideBinLocation) {
				e->Graphics->DrawString(bin, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
				xPos += convertViewWidthToPrintWidth(clmn_BinLoc->Width, bin->Length, ratio,3);
			}

			if (!pfwSettings->Print_HideOnHand) {
				e->Graphics->DrawString(onhand, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
				xPos += convertViewWidthToPrintWidth(clmn_OnHand->Width, onhand->Length, ratio,0);
			}

			if (!pfwSettings->Print_HideOnOrder) {
				e->Graphics->DrawString(onorder, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
				xPos += convertViewWidthToPrintWidth(clmn_OnOrder->Width,onorder->Length, ratio,0);
			}

			if (!pfwSettings->Print_HidePrice) {
				e->Graphics->DrawString(price, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
				xPos += convertViewWidthToPrintWidth(clmn_UnitPrice->Width,price->Length, ratio,0);
			}

			if (!pfwSettings->Print_HideCost) {
				e->Graphics->DrawString(cost, printUnderlineFont, Brushes::Black, xPos, yPos, new StringFormat());
			}
			count+=2;
			
             // Print each line of the file.
             while(count < linesPerPage && (moreLines=itemsToPrint->MoveNext()) ) 
             {

				 line = dynamic_cast<ListViewItem*>(itemsToPrint->Current);
                 yPos = topMargin + (count * printFont->GetHeight(e->Graphics));

				xPos = 0;
				if (!pfwSettings->Print_HideVendor) {
					value = convertViewWidthToPrintWidth(clmn_Vendor->Width, vendor->Length, ratio,0);
					e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[1]->Text,value,ratio,0), printFont, Brushes::Black, xPos, yPos, new StringFormat());
					xPos += (float)value;
				}

				if (!pfwSettings->Print_HideSubstitute) {
					value = convertViewWidthToPrintWidth(clmn_Subs->Width, substitute->Length, ratio,0);
					e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[2]->Text,value,ratio,0), printFont, Brushes::Black, xPos, yPos, new StringFormat());
					xPos += (float)value;
				}

				value = convertViewWidthToPrintWidth(clmn_Part->Width, part->Length, ratio,1);
				e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[3]->Text,value,ratio,1), printFont, Brushes::Black, xPos, yPos, new StringFormat());	
				xPos += (float)value;

				if (!pfwSettings->Print_HideDescription) {
					value = convertViewWidthToPrintWidth(clmn_Description->Width, description->Length, ratio,0);
					e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[4]->Text,value,ratio,0), printFont, Brushes::Black, xPos, yPos, new StringFormat());
					xPos += (float)value;
				}

				value = convertViewWidthToPrintWidth(clmn_Qty->Width, qty->Length, ratio,2);
				e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[5]->Text,value,ratio,2), printFont, Brushes::Black, xPos, yPos, new StringFormat());
				xPos += (float)value;

				if (!pfwSettings->Print_HideBinLocation) {
					value = convertViewWidthToPrintWidth(clmn_BinLoc->Width, bin->Length, ratio,3);
					e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[6]->Text,value,ratio,3), printFont, Brushes::Black, xPos, yPos, new StringFormat());
					xPos += (float)value;
				}

				if (!pfwSettings->Print_HideOnHand) {
					value = convertViewWidthToPrintWidth(clmn_OnHand->Width, onhand->Length, ratio,0);
					e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[7]->Text,value,ratio,0), printFont, Brushes::Black, xPos, yPos, new StringFormat());
					xPos += (float)value;
				}

				if (!pfwSettings->Print_HideOnOrder) {
					value = convertViewWidthToPrintWidth(clmn_OnOrder->Width, onorder->Length, ratio,0);
					e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[8]->Text,value,ratio,0), printFont, Brushes::Black, xPos, yPos, new StringFormat());
					xPos += (float)value;
				}

				if (!pfwSettings->Print_HidePrice) {
					value = convertViewWidthToPrintWidth(clmn_UnitPrice->Width, price->Length, ratio,0);
					e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[9]->Text,value,ratio,0), printFont, Brushes::Black, xPos, yPos, new StringFormat());
					xPos += (float)value;
				}

				if (!pfwSettings->Print_HideCost) {
					value = convertViewWidthToPrintWidth(clmn_Cost->Width, cost->Length, ratio,0);
					e->Graphics->DrawString(convertTextForPrintWidth(line->SubItems->Item[10]->Text,value,ratio,0), printFont, Brushes::Black, xPos, yPos, new StringFormat());	
				}
				 
                 count++;
             }
			
             // If more lines exist, print another page.
			 if (moreLines) {
				 e->HasMorePages = true;
			 } else {
				 e->HasMorePages = false;
			 }
		 }
		//This function takes care of the spacing between the fields
		private:float convertViewWidthToPrintWidth(int len, int textLen, double ratio, int vipField) 
		{
			//Minimum value a field is allowed to be moved
			float min=0;
			System::Drawing::Font* viewFont = lv_Parts->Font;
			
			//vipField's are Part, Qty and Bin
			//The title of the field (and the text underneath)
			//must be of a specified width.
			switch(vipField)
			{
				//Part
				case 1 :
					if(textLen<=15)
					{
						textLen += 15 - textLen;
					}
					break;
				
				//Qty
				case 2 :
					if(textLen<=4)
					{
						textLen += 4 - textLen;
					}
					break;
				
				//Bin
				case 3 :
					if(textLen<=10)
					{
						textLen += 10 - textLen;
					}
					break;
					
				default:		
					break;
			}
			
			//If no vip fields were encountered then use the textLen passed in
			min = ((textLen * (float)ratio)/viewFont->Size)*printFont->Size;

			//The actual width of the field selected by user on the main menu.
			float value = (len/viewFont->Size)*printFont->Size;

			//If the value is less than the minimum size setup above
			//set the value to the minimum.
			if(value < min)
			{
				value = min;
			}

			return value;
		}

		//This function will format the text passed in so that it will fit according
		//to the field width size established in convertViewWidthToPrintWidth(...).
		private:String* convertTextForPrintWidth(String* text, double value, double ratio, int vipField) 
		{	
			//Used below to determine if two fields are close together.
			double limit = 40.0;

			//Using the ratio we can find out how much space 
			//the text will need.
			double textRatio = text->Length * ratio;
			Boolean forLoopBreak = false;

			//If this is true the text is overlapping onto the next field
			if(textRatio > value)
			{
				//Loop through and while the text is overlapping
				//remove a char from the string until it no longer overlaps.
				for(int y = (text->Length - 1);y>0;y--)
				{
					textRatio = text->Length * ratio;
					
					//Vip fields are preset and should not have
					//chars removed unless larger than the allowable format.
					// Part(15), Qty(4), Bin(10)
					switch(vipField)
					{
						case 1 :
							if(text->Substring(0,y)->Length<=15)
							{
								forLoopBreak = true;
							}
							else
							{
								text = text->Substring(0,y);
							}
							break;
						
						case 2 :
							if(text->Substring(0,y)->Length<=4)
							{
								forLoopBreak = true;
							}
							else
							{
								text = text->Substring(0,y);
							}
							break;
						
						case 3 :
							if(text->Substring(0,y)->Length<=10)
							{
								forLoopBreak = true;
							}
							else
							{
								text = text->Substring(0,y);
							}
							break;
						default:
							text = text->Substring(0,y);
							break;
					}
					
					//Vip field is the right size
					//therefore break out of the loop.
					if(forLoopBreak == true)
					{
						break;
					}

					//Is it finally not overlapping?
					if(textRatio < value)
					{
						//If its close continue on and take another 
						//char off, otherwise break out.
						if((value - textRatio) < (ratio * 1.5))
						{
							continue;
						}
						else
						{
							break;
						}
					}
				}
			}
			else if((value>limit) && (text->Length * ratio) > (value - 40))
			{
				//If the app runs through here then two fields are near 
				//each other and have the danger of overlapping.  A field
				//being completely or semi covered by another field has already been 
				//taken care of.  
				//Therefore this block of code is when one field edge is very
				//close to another and yet the textRatio is NOT greater than value.
				//ie: Not overlapping but close.

				//This will represent just how close they are
				double difference = 0.0;
				difference = (text->Length * ratio) - (value - 40);
				
				//Never change preset vip fields in this case
				if(!(vipField>0))
				{
					//Close but not overlapping
					if(difference<10.0)
					{
						text = text->Substring(0, (text->Length));
					}
					else if(difference<15.0)//Too close, knock off a char
					{
						text = text->Substring(0, (text->Length - 1));
					}
					else if(difference<20.0)
					{
						text = text->Substring(0, (text->Length - 2));
					}
					else
					{
						text = text->Substring(0, (text->Length - 3));
					}
				}
			}

			return text;
		}

Has anyone dealt with complex printing like this before? Is there a more accurate way to determine spacing on the xaxis when printing?

I mean in the MSDN example above they have this:

linesPerPage = e->MarginBounds.Height / printFont->GetHeight(e->Graphics);

Which deals with figuring out exactly the amount of lines per page. I've since found you can't do this to find out the exact amount of chars you can go width wise. Like this:

charWidthPerPage = e->MarginBounds.Width / printFont->GetWidth(e->Graphics);

Unfortunately, printFont does not have a getWidth member. Thus my need for my ratio. I'd like to remove that ratio all together so I can exactly determine my xaxis spacing properly. The code is getting pretty complicated and it isn't even dead exact. Anyone have any suggestions? Tips, Tricks or helpful links?

Any help would be outstanding,
Todd
Last edited by LuciWiz : 31-Mar-2005 at 15:42. Reason: Please insert your C++ code between [c++] & [/c++] tags
 
 

Recent GIDBlogPython ebook by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
burning problems PLEASE PLEASE HELP kelticeire Computer Hardware Forum 4 01-Dec-2006 16:39
More Reading in problems swayp C++ Forum 7 27-Jan-2005 14:27
GeForce FX 5600 problems Peacemaker Computer Hardware Forum 24 18-Jul-2004 06:50
Chaintech Geforce 5600 FX problems bartster74 Computer Hardware Forum 8 04-May-2004 14:16
Installation problems arman Apache Web Server Forum 3 03-Feb-2004 13:02

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 08:43.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.