Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Release file 3

Status
Not open for further replies.

TariqMehmod

Programmer
Mar 4, 2004
100
PK
Sir I am converting frx into jpg then copy converted jgp file to clipboard.
So I have these codes

Code:
 Set Safety Off

Public yout
Do declaration
Do create_jpg
Do image_to_clipboard
*---------------------------------------------------------
* this procedure converts frx into jpg
Procedure create_jpg
m.yrep=Addbs(Justpath(Sys(16,1)))
Set Defa To (yrep)
m.yout=m.yrep+"output"

If !Directory(m.yout)
	Md (m.yrep+"output")
Else
	Erase (m.yout+"\*.*")
Endi

Local afile
afile=(_Samples + "\Solution\Reports\Colors.frx")

#Define OutputNothing -1
#Define OutputEMF 100
#Define OutputJPEG 102
#Define OutputGIF 103
#Define OutputPNG 104
#Define OutputBMP 105
#Define OutputTIFF 101
#Define OutputTIFFM 201

oListener =Newobject("ReportListener")
oListener.ListenerType=3
Report Form (afile) Preview Object oListener

myext=[.]+Alltrim('JPG')
ntype=OutputJPEG
m.yout=m.yrep+"output"

For nPageno=1 To oListener.PageTotal
	cOutputFile = m.yout+"\myreport"+Trans(nPageno)+myext
	oListener.OutputPage(nPageno, cOutputFile,m.ntype)
Next

If Not Inlist(ntype,OutputTIFFM,1000,1001)
	Run/N "explorer"  &yout
Endi

reporlistener=Null
Release ReportListener
Endproc

*---------------------------------------------------------
* this procedure copy converted jpg to bmp then copy bmp to clipboard
Procedure image_to_clipboard

#Define CF_BITMAP 2
#Define CF_DIB 8
#Define IMAGE_BITMAP 0
#Define LR_LOADFROMFILE 16
#Define LR_MONOCHROME 0x00000001

fso=Createobject("scripting.filesystemobject")
fld=fso.getfolder(yout) && read file from foldr one by one

For Each fil In fld.Files
	Local m.oo
	m.oo=Newobject("image")
	m.oo.Picture=m.yout+"\"+(fil.Name)

	Local lnWidth,lnHeight
	lnWidth=m.oo.Width
	lnHeight=m.oo.Height

	nBitmap=0
	hbm=0
	GdipCreateBitmapFromFile(Strconv(m.yout+"\"+(fil.Name)+0h00,5),@nBitmap)
	GdipCreateHBITMAPFromBitmap(nBitmap,@hbm,0)
	lhBmp = CopyImage(hbm, 0, m.lnWidth, m.lnHeight,0)
	If OpenClipboard(0)!= 0
		EmptyClipboard()
		SetClipboardData(CF_BITMAP, lhBmp)
		CloseClipboard()
	Endif
Next

Endproc
*---------------------------------------------------------
Procedure declaration

Declare Integer OpenClipboard In User32 Integer
Declare Integer CloseClipboard In User32
Declare Integer EmptyClipboard In User32
Declare Integer SetClipboardData In User32 Integer,Integer
Declare Integer LoadImage In WIN32API Integer,String,Integer,Integer,Integer,Integer
Declare Integer GetClipboardData In User32 Integer
Declare Integer GdipCreateBitmapFromHBITMAP In GDIPlus.Dll Integer, Integer, Integer @
Declare Integer GdipSaveImageToFile In GDIPlus.Dll Integer,String,String @,String @
Declare Long GdipCreateHBITMAPFromBitmap In GDIPlus.Dll Long nativeImage, Long @, Long
Declare Long GdipCreateBitmapFromFile In GDIPlus.Dll String FileName, Long @nBitmap
Declare Long    GdipCreateBitmapFromFile    In GDIPlus.Dll String FileName, Long @nBitmap
Declare Long CopyImage In WIN32API Long hImage, Long, Long, Long , Long
Endproc

The codes work fine FIRST time. no error occurs. you can see converted file bmp format in folder

But when I run above codes SECOND time then it show this error messages
is_cpasxy.png


Is it possible to get rid of this error message?

I hope error is in these lines

Code:
 nBitmap=0
	hbm=0
	GdipCreateBitmapFromFile(Strconv(m.yout+"\"+(fil.Name)+0h00,5),@nBitmap)
	GdipCreateHBITMAPFromBitmap(nBitmap,@hbm,0)
	lhBmp = CopyImage(hbm, 0, m.lnWidth, m.lnHeight,0)
	If OpenClipboard(0)!= 0
		EmptyClipboard()
		SetClipboardData(CF_BITMAP, lhBmp)
		CloseClipboard()
	ENDIF

Please help
 
Hello Tariq, how did you solve it?

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Respected Teacher GriffMG

I used these codes

Code:
 m.yrep=Getenv("TEMP")
Set Defa To (yrep)

xflname=""
ahour=Padl(Alltrim(Str(Hour(Datetime()))),2,'0')
amin=Padl(Alltrim(Str(Minute(Datetime()))),2,'0')
asec=Padl(Alltrim(Str(Sec(Datetime()))),2,'0')
xflname=Alltrim(Dtos(Date()))+"_"+ahour+amin
xflname=Alltrim(Dtos(Date()))+"_"+ahour+amin
xflname=Alltrim(Dtos(Date()))+"_"+ahour+amin+asec

m.yout=m.yrep+'\'+xflname

If !Directory(m.yout)
	Md (m.yrep+'\'+xflname)
Endi

Every I run codes then a new folder with unique name like this

20201201_160721 is created in TEMP folder and all jpg files are saved there.
In this way there is no chance for sharing violation.

But my sir ...

I sure this is not a right way to get rid of error message "File access is denied"

There was no way except this for me to make codes work properly.

I am still looking forward you to release JPG file from memory.

Regards



 
I think you have the jpg open in explorer still, you need to close it before you delete...

You could do a TRY ENDTRY construct... around the delete

Or maybe open it in something other than explorer?

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
Respected Sir,

I have commented these lines

First

Code:
 &&If Not Inlist(ntype,OutputTIFFM,1000,1001)
	&&Run/N "explorer"  &yout
Endi

So there is no chance the file is opened in Explorer

I suspect there are 2 more place there file can be opened

Code:

In the last line word Preview has been used, may be file is in preview state

Second

Code:
 nBitmap=0
	hbm=0
	GdipCreateBitmapFromFile(Strconv(m.yout+"\"+(fil.Name)+0h00,5),@nBitmap)
	GdipCreateHBITMAPFromBitmap(nBitmap,@hbm,0)
	lhBmp = CopyImage(hbm, 0, m.lnWidth, m.lnHeight,0)
	If OpenClipboard(0)!= 0
		EmptyClipboard()
		SetClipboardData(CF_BITMAP, lhBmp)
		CloseClipboard()
	ENDIF

May be file is in memory while copying to clipboard

Regards
 
The whole point about putting it in the Temp folder is that there is no need to explicitly delete it. Your users (or admins) should be doing a weekly cleanup, and this will clear out all the old temp files.

Alternatively, what happens if you give the listener's OutputPage method the name of a file that already exists? If it overwrites the file without warning (perhaps with SET SAFETY OFF?), then you don't need to generate a new filename each time, and you don't need to explicitly delete the file. Just give it the same filename each time. Place the file in one of the user's personal folders (such as My Documents or Temp) to avoid multi-user clashes.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 

Sir, actually the number of files may be different every time.
It depends on the number of pages of selected frx.
I have tested
Code:
 SET SAFETY OFF
but it also does not allow to delete or overwrite files.

Regards
 
Hi,

... or simply use xFile = TTOC(DateTime(), 1) which will generate a string format "YYYYMMDDhhmmss"

hth

marK
 
I just checked on how I do this in my reporting.

Background:
4 different output tools (UNIX apps, VFP, Crystal Reports and a ReST based web tool)
70+ different report groups
99+ different individual variants for each group
15 different output types per variant (PREVIEW/JPG/DOC/XLS/PDF/EMAIL/...)
Users can combine groups/variants/outputs within one single printing call, so 1 to x reports are computed/produced

Generated files are placed in a subdirectory of our installation directory (.\reporting\output\)
Every day a new subdirectory is generated automatically by the first generated output (.\reporting\output\20201201\)
Each temporarily generated file is named like this: 20201201_093029_5X80KDNZK (YYYYMMDD_hhmmss + SYS(2015))+ Type specific suffix
Even with 200+ users we haven't had name doubles yet.

Within our app configuration, customers can set the time period for storage for those files from 0 (forever) to 999 days.
First User of the day automatically starts a cleanup routine whose sole purpose is checking storage directories and delete all files outside of the defined period.

So,...why did we do this?
- Using USER/TEMP was never cleaned by our customers majority
- Access to USER/TEMP is only available for the current user, so no centralized cleanup routine
- Having access to a central point for all users and admins for automatied postprocessing of the files like archive keywording
- Optional use of a dedicated print server
and some other reasons I've forgotten long ago :)

Therefore, we never messed with USER/TEMP. It's more than enough, that VFP places all its own temp files there. :)

JM2C


-Tom
 
Pretty easy to clean up USER/TEMP. Something like this:

Code:
old_err=ON('ERROR')
ON ERROR *
DELETE %TEMP%\*.*
ON ERROR &old_err
 
Hi Dan,

yes you can do this for the current user or every user that logs in to the app. But to me it doesn't make sense to place reporting files into 200+ user/temp directories, or only 10 different directories.
User/Temp simply is to restrictive for that.
I prefer administrating my own directories with one hit.
My advice for cleaning up USER/Temp with a script, like the one so show but as powershell script, is that it has to be done by the system admins of our customers and not by our software. Thats simply M$ philosophy, otherwise VFP would clean up behind itself within USER/Temp, wouldn't it? :)
Offering my own TEMP direcory(ies) make the customer independent from any admin scripts that might interfere with app data that has to stay longer than an admin might expect.

But it is more or less the same as logging into user specific daily logfiles instead of writing into windows protocol databases like Application, Security, Installation, System a.s.o. We offer this as an option within our config but no one wants to use it. The customer admins prefer our logfiles.

2 people = 3 different tastes and this comes to an extreme as soon as this means customer and admin :)

JM2C

-Tom
 
My Dear Seniors.

I could not found the solution of real problem described in 1st post of this thread.
On what destination my jpg file stops/hangs and not ready to go out.
If we get success to kick that file out then no needs to create huge number of folders daily in temp.

Please
 
@Tom

Actually, my example was only "proof of concept" :)
In reality at first startup for the day (determined from if I can get exclusive access to a certain DBF), if no C:\TEMP exists, I try to make it and set the environment variables %TEMP% and %TMP% to that. Since this was coded before TRY/CATCH was introduced I use the same ON ERROR-technique as in the former example to not get errors. If it fails for some reason, I'll let it be as it is.
 
I tried to free the files by EmptyClipboard(), but that doesn't work, too.

Besides this, all I can contribute is that the files can be erased when you don't call image_to_clipboard, so you have the right idea, Tariq, it's about this code. I don't see a way to mend this, so you better live with this approach of leaving files and creating unique names. As you see from others it's not an unusual approach, as you don't always have all control about such things as file handles. Once Foxpro or your application quits the files are released and can be deleted.

Perhaps make the best of it by making it a feature, not a bug: Use already created images to allow repeat reporting without a rerun of the report.

PS: You can use LoadImage() API function and get a bitmap handle to use for SetClipvoardData(), like this:

Code:
For Each fil In fld.Files
   hBitmap = LoadImage(0, m.yout+"\"+fil.Name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)
   If OpenClipboard(0)!= 0
      SetClipboardData(CF_BITMAP, hBitmap)
      CloseClipboard()
      ERASE (m.yout+"\"+fil.Name)
   Endif
Next

You just have to change your output to BMP files, LoadImage only works with the BMP format.

Chriss
 
Respected Sir Chris Miller

I tested your following codes

Code:
 Declare Integer OpenClipboard In User32 Integer
Declare Integer CloseClipboard In User32
Declare Integer EmptyClipboard In User32
Declare Integer SetClipboardData In User32 Integer,Integer
Declare Integer LoadImage In WIN32API Integer,String,Integer,Integer,Integer,Integer
Declare Integer GetClipboardData In User32 Integer
Declare Integer GdipCreateBitmapFromHBITMAP In GDIPlus.Dll Integer, Integer, Integer @
Declare Integer GdipSaveImageToFile In GDIPlus.Dll Integer,String,String @,String @
Declare Long GdipCreateHBITMAPFromBitmap In GDIPlus.Dll Long nativeImage, Long @, Long
Declare Long GdipCreateBitmapFromFile In GDIPlus.Dll String FileName, Long @nBitmap
Declare Long    GdipCreateBitmapFromFile    In GDIPlus.Dll String FileName, Long @nBitmap
Declare Long CopyImage In WIN32API Long hImage, Long, Long, Long , Long

#Define CF_BITMAP 2
#Define CF_DIB 8
#Define IMAGE_BITMAP 0
#Define LR_LOADFROMFILE 16
#Define LR_MONOCHROME 0x00000001

cFile='C:\Windows\winsxs\x86_setup-uxwizard-clientimages_31bf3856ad364e35_6.1.7600.16385_none_48ada01d8ff36e68\background.bmp'

hBitmap = LoadImage(0, cFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE)

MESSAGEBOX(hBitmap)

If OpenClipboard(0)!= 0
	SetClipboardData(CF_BITMAP, hBitmap)
	CloseClipboard()
	Erase cFile
Endif

but this line always return 0
Code:
 MESSAGEBOX(hBitmap)

File can not be copied to clipboard until hBitmap contains values more than 0

Please help
 
Dear Tariq,

how do you think you get hBitmap>0, if you don't generate BMP files? Of course my code is not all you need and you only added declarations. The for loop I posted has to replace the for loop within the image_to_clipboard procedure. And I told you:

Chriss said:
You just have to change your output to BMP files, LoadImage only works with the BMP format.

This means changing the create_jpg procedure. You have all constants necessary to do that yourself. I intentionally don't post the full code here, this is against netiquette to create endless threads by reposting all code and as asker you should be capable to at least understand the rough structure of your code and see what goes where. The procedures you have are telling you what they do, create_jpg creates jpgs, it's that simple, and if I tell you that now has to be changed to BMP instead of JPG, do you really don't know what to do in that procedure?

I'm not angry at you, I understand you're a poor chap, who has to do a little task you actually can't do. In the long term, you either learn this or hire someone to do this part or - if you're an employee - find a workmate helping you with it.

PS: I'll point you to it as a little service: This is your loop (shortened):
Code:
For Each fil In fld.Files
	Local m.oo
...
Next

This has to be replaced with mine. And make the move to BMP.

Chriss
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top