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!

drawing to a device context

Status
Not open for further replies.

aejester

Programmer
Aug 29, 2001
52
CA
Hi,

I've used the code found here...
to generate a device context and load it to a picture box.

How would you manipulate this device context (ex. drawing lines on it similar to that of drawing lines on a picture box)???

Is this even possible?
 
Here is some code for you. You will need a command button and a picture box with the default names.

Option Explicit

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
'-----------------------------------------------------------------------------------------------------------------------
Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
'-----------------------------------------------------------------------------------------------------------------------
Private Declare Function SetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, _
ByVal crColor As Long) As Long
'-----------------------------------------------------------------------------------------------------------------------
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, _
ByVal nHeight As Long) As Long
'-----------------------------------------------------------------------------------------------------------------------
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
'-----------------------------------------------------------------------------------------------------------------------
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
'-----------------------------------------------------------------------------------------------------------------------
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth _
As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) _
As Long
'-----------------------------------------------------------------------------------------------------------------------

Private Sub Command1_Click()
Dim hBmp As Long
Dim hdc As Long
Dim iX As Long
Dim iY As Long
Dim iZ As Long

hBmp = CreateCompatibleBitmap(Picture1.hdc, Picture1.ScaleWidth, 256)
hdc = CreateCompatibleDC(Picture1.hdc)
SelectObject hdc, hBmp

For iY = 0 To 255 'This fills the backgroung
iZ = 255 - iY
For iX = 0 To Picture1.ScaleWidth
SetPixel hdc, iX, iY, RGB(iY, iY, iZ)
Next
Next

For iY = 100 To 104 'This draws 5 Horizontal lines
For iX = 0 To Picture1.ScaleWidth
SetPixel hdc, iX, iY, RGB(0, 0, 0)
Next
Next

For iX = 100 To 104 'This draws 5 Vertical lines
For iY = 0 To 255
SetPixel hdc, iX, iY, RGB(255, 255, 255)
Next
Next

BitBlt Picture1.hdc, 0, 0, Picture1.ScaleWidth, 256, hdc, 0, 0, &HCC0020

Call DeleteDC(hdc)
Call DeleteObject(hBmp)
End Sub


Hope this helps. [spin] If you choose to battle wits with the witless be prepared to lose.
[machinegun][hammer]
 
ok, so all drawing to the dc has to be done pixel by pixel? Maybe this isnt as good as I thought.

I have an entire map drawn on a picture box (extracted from a dxf file) and I have to be able to zoom in out and move around the map. So I was hoping to draw the entire map image to a device context instead then BitBlt the respective region onto the picture box depending on where the user has navigated/zoomed.

But if this has to be done pixel by pixel (and I would be drawing circles, text, and lines of all angles) then maybe this isnt the best option. Do you or anyone else have any ideas on the best way to accomplish this?

Thank you for your time!
 
You don't have to draw it a pixel at a time. There is a LineTo API and an ArcTo API Function as well. You will need to move the current position around with the MoveToEx API to get the starting point. Does that help? If you choose to battle wits with the witless be prepared to lose.
[machinegun][hammer]
 
aejester, if you get some simple example code together that demonstrates drawing, printing text & loading to picture box (or saving to file?) I think it would have general interrest (I'll be interrested anyway). Could you then post it here?

or anyone else that happens to have a snipplet at hand...

thx in advance Sunaj
'The gap between theory and practice is not as wide in theory as it is in practice'
 
Sure, when (if) i get something working I'll post a sample project.
 
aejester,

What method did you use to get the information from the .dxf file into the picturebox? In my current project, I have to open the .dxf file in Autosketch, highlight it and copy it to the clipboard, then paste it into a picturebox in my program. If I can read the .dxf file directly ( without having to pay for a 3rd party control ) that would simplify things greatly.

Thanks,

Robert
 
There is a dxf SDK that can be found at (just look up dxf there and you'll find it). This is what I used (as well as looking at a sample map that I had) to figure out what all the codes mean.

DXF Files are very large and therefore it is quite inefficient to use them, but I don't have a lot of choice.

It is pretty simple to parse the dxf files for certain objects but the difficult part gets to be when there are blocks (which are objects defined once but used throughout the drawing). This is because you have to have a way of storing the drawing instructions for each block (I think) and on each occurence of the block you need to execute those instructions.

In any case, I'm still not 100% finished the actual dxf translation routine yet, but I can at least see something that greatly resembles the original dxf drawing on my picture box.

For sample code, just send me an email and I'll send you something (maybe over the weekend) that might help you out as the code is too long to post here.

clint_olsen@yahoo.com
 
Thanks for the link. I downloaded the files for the DXF and DWG formats. Unfortunatly they didn't have one for the SKF format, but the other two should work OK.

You can email me at NumberOneVampire@yahoo.com

Thanks,

Robert
 
SKF is the default format for AutoSketch, made by Autodesk. It's sort of a lightweight CAD program, that does not have 3D stuff in it. The program used to be called "Drafix CAD" but they were bought out by Autodesk and the program re-released and renamed. You can read and save the files in DXF or DWG when using AutoSketch if you want to though.

Robert
 
Hmm...

I've encountered a problem here.

When you draw a line, arc, or point on a picture box using the given methods, it draws it according to the scale used.

So if the picture box has previously been set to have a scale of (50000, 50000)-(55000, 55000) then when you draw a line using Picture1.Line(51000, 51000)-(54000, 54000) it draws in the correct location.

However, since I am trying to draw to a device context, I have to use the API to draw everything. The problem is that the device context does not seem to have the same scale as the picMap picturebox. Is there any way to set the scale of a memory device context so that it behaves similarly to that of a picturebox control (probably API???)?

This...
MoveToEx myhdc, 51000, 51000 'This sets the start point
LineTo myhdc, 54000, 54000 'This draws the line
....will no longer work on the dc!!!

By the way, just to refresh everyones memory, I'm using this to initialize the dc

Dim hBmp as Long
Dim myhdc as Long 'The hdc of the device context
hBmp = CreateCompatibleBitmap(picMap.hdc, picMap.ScaleWidth, picMap.ScaleHeight)
myhdc = CreateCompatibleDC(picMap.hdc)
SelectObject myhdc, hBmp
 
Hi,

Using API drawing, everything is measured in pixels. The standard scale in a picturebox is twips, so set the .scalemode of the picturebox to vbpixels - and it should fit together. If you for some reason likes to keep the twips in the picturebox you can use the methods .scalex .scaley of the pictuebox to convert between the scales.
Sunaj
'The gap between theory and practice is not as wide in theory as it is in practice'
 
API drawing is not necessarily in pixels; the important point is that the default MapMode (more-or-less the equivalent of VB's ScaleMode) for a new device context is mm_text, which happens to map one device unit to one logical unit, which means that on a screen device we end up working in pixels. However the MapMode can quickly be changed through the SetMapMode API call. In combination with the GetMapMode function it can be used to ensure two device contexts use the same drawing scale, eg:
[tt]
Private Declare Function GetMapMode Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function SetMapMode Lib "gdi32" (ByVal hdc As Long, ByVal nMapMode As Long) As Long

' Match target DC's MapMode to that of source DC
SetMapMode hDCTarget, GetMapMode(hdcSource)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top