یکی از مشکلاتی که برنامه نویسان ویژوال فاکس پرو ممکن است با ان مواجه شوند ، چاپ محتوای Tree خواهد بود.در این مقاله سعی میکنم تا راههایی را در راستای حل این مشکل ارائه دهم.
پیشاپیش از نظرات سازنده شما خواننده محترم برای کامل کردن روشهای زیر استقبال می کنم.

مقدمات
برای این مقاله جدولی بنام groups را با ساختار زیر در نظر میگیریم:
Autoinc id
Integer g_id
Charactername
این یک ساختار استاندارد با حداقل  تعداد فیلد است که در تصویر زیر نمونه اطاعاتی که در مثالمان استفاده کرده ایم را میتوانبد مشاهده کنید :
اطلاعات جدول گروه
در اینجا توضیح اندکی راجع به نحوه نمایش این اطلاعات در شئ Tree خواهیم داشت . یک فرم ساخته و  با انتخاب گزینه ActiveX Control یک شئ  Microsoft TreeView Control را روی فرم قرار میدهیم و بنام
oTree تغییر نام میدهیم . سپس در متد Init آن کد زیر را مینویسیم :
Select groups
Go Top
Set Filter To g_id=0
Scan
   This.oTree.Nodes.Add(,1,"g"+Alltrim(Str(groups.Id)),Alltrim(groups.Name))
Endscan
Set Filter To
Go Top
همچنین کد زیر را در متد NodeClick شئ oTree قرار دهید :
Local ParentId
If Not Isnull(This.SelectedItem)
   Thisform.nodekey=Alltrim(Node.Key)
   Thisform.pageframe1.page1.txtParent.Value=Alltrim(Node.Text)
   Thisform.pageframe1.page2.txtName.Value=Alltrim(Node.Text)
   ParentId=Right(Node.Key,Len(Node.Key)-1)
   Select groups
   Set Filter To g_id=Val(ParentId)
   If Node.children=0
       Scan
           This.Nodes.Add(Node.Key,4,"g"+Alltrim(Str(groups.Id)),Alltrim(groups.Name))
       Endscan
   Endif
   Set Filter To
   Go Top
Endif
به این ترتیب شما با کلیک بر روی هر گره پدر در صورت وجود فرزندان آن به درخت اضافه میشوند . حال شما یک Tree دارید که میخواهید امکان چاپ محتویات آن را به کاربر بدهید.
تبدیل
ساده ترین راه چاپ خود شئ درخت هست . یعنی تلاش کنیم تا چارچوب این کنترلرا در یک فایل گرافیکی ذخیره کنیم  وآن را چاپ کنیم .همین چاپ کردن باز بهطرق مختلف قابل انجام هست که در ادامه به شرح کامل این روش میپردازیم.
جهت تبدیل این چارچوب به یک فایل گرافیکی نیاز به برنامه ای داریم تا بتواند با دریافت دستگیره (handle) شئ oTree آن را تبدیل کند ، اگر از ویرایش 9.0 ویژوال فاکس پرو استفاده میکنید میتوانید از کتابخانه قدرتمند GDIPlusX استفاده کنید ما در این مقاله از کلاس GPImage استفاده میکنیم و دلیل آن اینست که این کلاس در ویرایش های 6.0 تا 9.0 ویژوال فاکس پرو قابل استفاده است.
ما از کد زیر برای تبدیل و نمایش فایل گرافیکی استفاده میکنیم :
#include gpImage.h
LOCAL fname
fname=GETENV("TEMP")+"_"+SUBSTR(SYS(2015), 4)+".jpg"
DECLARE INTEGER ShellExecute IN SHELL32 INTEGER, STRING, STRING, STRING, STRING, INTEGER
IF NOT "gpImage" $ SET("Procedure")
   SET PROCEDURE TO gpImage ADDITIVE
ENDIF
gdip = CREATEOBJECT("gpInit")
img = CREATEOBJECT("gpImage")
img.Capture(THISFORM.otree.HWND)
img.SaveAsJPEG(fname)
RELEASE img
RELEASE gdip
ShellExecute(0,"open",fname,"","",1)
در توضیح کد بالا اینکه در خط اول فایل حاوی تعاریف مورد نیاز کلاس gpimage در برنامه وارد میشود در خط بعد یک متغییر محلی برای ذخیره نام فایل تعریف شده و در خط بعد مقدار دهی میشود.
در خط چهارم تابع ویندوزی ShellExecuteفراخوانی میشود . سپس یک نمونه از کلاس گرافیکی ساخته شده و همینطور یک نمونه از کلاس تصویر بعد از آن با اعلام هندل شئ به متد Capture شئ تصویر ، تصویر آن تولید میشود و به فرمت Jpeg ذخیره میکنیم و نمونه ها را از حافظه پاک میکنیم  در نهایت هم با استفاده از تابع ویندوزی آن را نمایش میدهیم.
این شرح کلی کد بالا است شاید اینجا این سئوال مطرح شود که چرا از تابع ShellExecute استفاده شده است؟ در جواب باید گفت که با این انتخاب میتوان چندید هدف را زد :
اول اینکه این تابع برنامه ای را که در ویندوز وظیفه نمایش این نوع فایل را بر عهده دارد را صدا میزند و ما از بابت نمایش آن خیالمان آسوده است و
دوم اینکه با تغییر دستور بالا به شکل زیر میتوان آن تصویر را مستقسم به چاپگر فرستاد بدور از دغدغه تغییر اندازه و یا کیفیت آن البته از همان کلاس گرافیکی نیز میتوان استفاده کرد :
ShellExecute(0,"print",fname,"","",1)
این یکی از راههای چاپ تصویر بود راه دیگر این است که اگر شما بخواهید متنی و یا اطلاعاتی اضافه را نیز به همراه آن چاپ کنید میتوانید یک کرسر با یک فیلد General  بسازید و از دستور زیر استفاده کرده و محتویات آن فایل را به جدول اضافه کنید تا بتوانید در گزارش خود با استفاده از یک فیلد تصویر آن را نمایش و چاپ کنید :
APPEND GENERAL GeneralFieldName [FROM FileName] 
  [DATA cExpression] [LINK] [CLASS OLEClassName]
اما شاید شما هم به مشکل من بخورد کنید ، به تصاویر زیر دقت کنید :
همانطور که ملاحظه میکنید مشکل زمانی پیش می آید که شئ Tree ما دارای Scroll bar  بشود وغیر از برنامه های مخصوص این کار مانند Snag It چاره دیگری برای تبدیل کامل آن به فایل گرافیکی نیست ، برای حل این مسئله راه حل دوم را مطرح میکنیم.
اطلاعات
در این راه حل سعی میکنیم تا به نحو خاصی اطلاعات را در یک کرسر دیگر بریزیم که بتوانیم توسط یک گزارش معمولی در ویژوال فاکس پرو چاپی همانند Tree را شبیه سازی کنیم خاصیت این روش برداشته دشن قید محدودیت رکوردها است برای این کار از کد زیر استفاده میکنیم :
Use Locfile("groups","dbf")
ret_tree(0,0)
Select test
Report Form report2 Preview

Function ret_tree(p_id,k)
Local i,j,larr[1,3],rnum
Select * From groups Where g_id=p_id Into Cursor tmp
rnum=Reccount()
If rnum>0
   Dimension larr[rnum,3]
   j=1
   Scan
       larr[j,1]=tmp.Id
       larr[j,2]=tmp.Name
       larr[j,3]=tmp.g_id
       j=j+1
   Endscan
Endif
Use
If rnum>0
   k=k+3
   For i=1 To rnum
       Insert Into test (Name) Values (Alltrim(larr(i,2))+Replicate(" ",k)+".")
       ret_tree(larr(i,1),k)
   Endfor
Endif
Endfunc
در این کد با استفاده از یک تابع بازگشتی هر شاخه از درخت را پیمایش کرده و بترتیب آنها را در یک کرسر که تنها حاوی یک فیلد کاراکتری است ذخیره میکنیم و یک گزارش ساده تنها با یک فیلد که متصل به کرسر است را صدا میزنیم ، اما نکته اصلی در دستور insert است که ما در هر پله متناسب با آن مقداری فضای خالی به رشته اضافه میکنیم تا بتوانیم شبیه سازی خود را کامل کنیم البته شما با تغییر مقدار اضافه شده به متغییر k میتوانید طول فاصله را به میل خود تغییر دهیم.
اما سئوالی که ممکن است مطرح شود این است که چرا از آرایه استفاده کرده ایم؟ توضیح اینکه در ویژوال فاکس پرو در یک تابع بازگشتی همانند متغییرها نمیتوان از جداول استفاده کرد اما مثلا در php این امکان هست و این برمیگردد به اصول ویژوال فاکس پرو که هر جدول در یک ناحیه کاری باز میشود و اگر بخواهیم از آن استفاده کنیم هر مرحله فقط همان جدول اولیه را داریم حتی اگر از دستور Create Cursor استفاده شود.
در ادامه نمونه تولید شده توسط گزارش را مشاهده میکنید :

جهت مشاهده عکس ها در اندازه واقعی روی آنها کلیک کنید

منبع : بخش مقالات وب سایت برنامه های بی نیاز
تاریخ نگارش مقاله : 1387/11/28