Link to home
Start Free TrialLog in
Avatar of smith_c
smith_c

asked on

VB 6.0 Graphics

I am experiencing immense frustration at the moment...

I have created an application in visual basic (v6.0) which will open up a tiff file of an a1/a2 size drawing (using a Wang Image Edit control), and will shrink the file down to 200 x 200 a convert it to an anti-aliased bitmap(using the .Zoom property of the Wang Image control, and PlgBlt ing the resultant image into a picture box).

Here is the catch - the above procedure works fine when the form is visible and uppermost on the screen - however I wish to run the application in the background, without having the form appear on the screen.  Is there any way of fooling the operating system into thinking that the form is visible, so that the following piece of code works whether the form is visible or not?


Thankyou in anticipation

Chris

The subroutine I am using follows....




Private Sub ThumbImage(strFileName As String)
 'Procedure to "Thumbnail" a tiff file
 'Input file is an A1/A2 scanned image, in tiff format.
 'Output (hopefully) is a bitmap file of maximum 200 x 200 pixels
 '
 ' wimgThumbnail  : Wang Image edit control
 ' picThumbnail   : PictureBox control, with autoredraw property set to true

 Const MAX_WIDTH As Integer = 200
 Const MAX_HEIGHT As Integer = 200
 Dim fromDC As Long
 Dim Pll(0 To 2) As POINTAPI
 Dim blnShouldScale As Boolean
 Dim lNewZoom As Long
 Dim lImgWidth As Long
 Dim lImgHeight As Long
 Dim sngAspectRatio As Single
 Dim lRetVal As Long


 'Display the tiff file in the Wang Control
 wimgThumbnail.Image = strFileName
 wimgThumbnail.Display
 wimgThumbnail.Refresh

 blnShouldScale = False
 lImgWidth = wimgThumbnail.ImageWidth
 lImgHeight = wimgThumbnail.ImageHeight


 'Scale the image, so that it can be shrunk into a 200 x 200 picturebox
 lNewZoom = 100
 Do While ((lImgWidth * lNewZoom / 100 * 0.02) > MAX_WIDTH) Or ((lImgHeight * lNewZoom / 100 * 0.02) > MAX_HEIGHT)
  blnShouldScale = True
  lNewZoom = lNewZoom - 1
 Loop

 If (blnShouldScale) Then
  wimgThumbnail.Zoom = lNewZoom
  wimgThumbnail.Refresh
 
  wimgThumbnail.SaveAs "c:\test.tif", 1, 3, 1, 0, True

  wimgThumbnail.Image = "c:\test.tif"
  wimgThumbnail.Display
  wimgThumbnail.Refresh
 End If

 lImgWidth = wimgThumbnail.ImageWidth
 lImgHeight = wimgThumbnail.ImageHeight

 sngAspectRatio = lImgWidth / lImgHeight

 If (sngAspectRatio >= 1#) Then
  wimgThumbnail.Width = MAX_WIDTH + 1
  wimgThumbnail.Height = MAX_HEIGHT / sngAspectRatio + 1
 Else
  wimgThumbnail.Height = MAX_HEIGHT + 1
  wimgThumbnail.Width = MAX_WIDTH * sngAspectRatio + 1
 End If

 imgThumbnail.FitTo 0, True
 'The image in the Wang Image edit control is now correctly scaled
 imgThumbnail.Refresh

 
 Pll(0).x = 0
 Pll(0).y = 0
 Pll(1).x = wimgThumbnail.Width - 1
 Pll(1).y = 0
 Pll(2).x = 0
 Pll(2).y = wimgThumbnail.Height - 1
 
 fromDC = GetDC(imgThumbnail.hwnd)

 'Size the picture box in correct proportions
 picThumbnail.Width = wimgThumbnail.Width - 1
 picThumbnail.Height = wimgThumbnail.Height - 1
 DoEvents

 lRetVal = PlgBlt(picThumbnail.hdc, Pll(0), fromDC, 0, 0, wimgThumbnail.Width - 1, wimgThumbnail.Height - 1, 0, 0, 0)
 ReleaseDC wimgThumbnail.hwnd, fromDC

 'Save the picturebox image to a .bmp file
 SavePicture picThumbnail.Image, "C:\test.bmp"
End Sub

Avatar of Erick37
Erick37
Flag of United States of America image

For regular PictureBoxes, setting
pb.Autoredraw = True
pb.Visible = False
will do the trick.

Perhaps the same is true for the Wang control.
Just posting so I can read later..
Avatar of smith_c
smith_c

ASKER

Sorry Erick37 - I have tried that, and it does not appear to work...
Have you tried calling the picturebox refresh method after you have PLGBlt the picture into the picture box.

This is a difference from vb 5.0 to vb6.0 where as in vb5.0 you did not need to call the refresh method after blting to a picture box in vb6.0 you do. As this is meant to save time if you have a number of blt's to the same picture box you can call the refresh once at the end rather than like in vb5.0 where it would be called automatically after each blt.


Hope this helps

Cheers

James
Avatar of smith_c

ASKER

James_stillman

Like I say in the preamble, the routine works fine when the form is visible, but PLGBlt copies a blank bitmap to the picturebox when the form is not visible.

Thanks

Chris
I'm sorry to say that I think it's not possible. Because the Bltbit must use in a visible enviroment, if it's invisible, where the position you specified, what on the position will be copied. Like your form invisible, the position won't be a picture or any think on it, only a blank there.
---That's I thought.


prefix
Does lRetVal return a success code?
Is fromDC always <> 0?
Try using StretchBlt instead of PlgBlt.
I dont want to sound nasty but why don't you

     Move 2 * Screen.Width, 0

your form before Show-ing it?

</wqw>
Avatar of smith_c

ASKER

Sorry wqw, this answer makes no apparent sense (in the context of my question)

Chris
Avatar of smith_c

ASKER

Adjusted points to 800
Avatar of smith_c

ASKER

Erick37

The result with StretchBlt is the same.  The subroutine works fine when the form is visible, but the bitmap blted is blank when the form is invisible.

Chris
"Is there any way of fooling the operating system into thinking that the form is visible, so that the following piece of code works whether the form is visible or not"

I suppose this way you can "fool" OS it's visible when the user can't see it.

</wqw>
look, there is no way to blit without first showing the DC. you must be happy you can get fromDC from hwnd of a not-shown window.

don't know of a way to "fool" it (like posting WM_PAINT etc. messages) other way than plain showing it somewhere. btw, i'm not sure if showing it outside screen is not optimized to NOT send WM_PAINT at all. (meaning that even Showing it won't work:-)

</wqw>
look, there is no way to blit without first showing the DC. you must be happy you can get fromDC from hwnd of a not-shown window.

don't know of a way to "fool" it (like posting WM_PAINT etc. messages) other way than plain showing it somewhere. btw, i'm not sure if showing it outside screen is not optimized to NOT send WM_PAINT at all. (meaning that even Showing it won't work:-)

</wqw>
look, there is no way to blit without first showing the DC. you must be happy you can get fromDC from hwnd of a not-shown window.

don't know of a way to "fool" it (like posting WM_PAINT etc. messages) other way than plain showing it somewhere. btw, i'm not sure if showing it outside screen is not optimized to NOT send WM_PAINT at all. (meaning that even Showing it won't work:-)

</wqw>
Avatar of smith_c

ASKER

wqw

The painting of the Wang Image control is optimised, but is there no way of invalidating the device context when it is not visible - ie forcing a repaint.

Chris
ASKER CERTIFIED SOLUTION
Avatar of Mac16426
Mac16426

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial