Sign in to follow this  
Followers 0
matrix200

Using Polygon windows api function

5 posts in this topic

I am still trying to make the needle of my clocks a little nicer ;)

I want to use Polygon windows api function.

Here is the quote from MSDN :

BOOL Polygon(

HDC hdc, // handle to DC

CONST POINT *lpPoints, // polygon vertices

int nCount // count of polygon vertices

);

Would it be possible to use that function?

If so how could I call it with an array of 3 points?

Right now I settled with just drawing 3 lines to make it , but it seems to be somewhat cpu heavy and I get some flickering (This time because it just takes a while to draw them).

Share this post


Link to post
Share on other sites



Why does it take a while to draw them? What pen/brush are you using?

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Well I am using the default brush (not selecting any).

First of all I need to calculate a point of intersection of a line and a circle to determine the length of those lines.

Then I draw a line from a place on a circle towards its center ,small horizontal line and then line back to the circle where it started.

I am using regular solid pen with width of 1.

Of course I draw everything twice because first I need to erase the previous graphic (just drawing with background color) then drawing with black.

Here is some code to illustrate

CODE

Func Update() ;Updates position of a needle (Just for testing)

$point = GetPoint($x)

;$point1 = GetPoint($x + 5)

DrawLine($point[0] , $point[1] , 59, 70 , 1, 0xC8D0D4)

DrawLine(59 , 70 , 61 , 70, 2, 0xC8D0D4)

DrawLine(61 , 70 , $point[0] , $point[1], 1, 0xC8D0D4)

;UpdateLinePosition($x + 5 , $y + 5, 70 , 70, $x , $y , 70, 70)

$x = $x + 5

;$y = 10

if $x > 110 Then

$x = 10

;$y = 10

EndIf

$point = GetPoint($x)

DrawLine($point[0] , $point[1] , 59, 70 , 1, 0x0)

DrawLine(59 , 70 , 61 , 70, 2, 0x0)

DrawLine(61 , 70 , $point[0] , $point[1], 1, 0x0)

EndFunc

Func getPoint($coordX );y is assumed to be 10 (draw a line )

Dim $result[2]

Local $coordY = 10

Local $a1, $b1 ,$a, $b , $c

if $coordX == 60 Then

$result[0] = 60

$result[1] = 20

Return $result

EndIf

$a1 = (70 - $coordY ) / (60 - $coordX );determine tangent of a line passing through given point and circle center

$b1 = 70 - ($a1 * 60 )

$a = ($a1 * $a1) + 1

$b = -120 - (140 * $a1) + (2 * $a1 * $b1 )

$c = ($b1 * $b1 ) - (140 * $b1 ) + 6000

$b24ac = sqrt(($b * $;) - (4 * $a * $c))

$result1X = ( -$b + $b24ac) / (2* $a)

$result2X = ( -$b - $b24ac) / (2* $a)

$result1Y = $a1 * $result1X + $b1

$result2Y = $a1 * $result2X + $b1

if $result1Y < 70 Then

$result[0] = Round($result1X)

$result[1] = Round($result1Y)

Else

$result[0] = Round($result2X)

$result[1] = Round($result2Y)

EndIf

;ConsoleWrite($result1X & " " & $result1Y & @CRLF & $result2X & " " & $result2Y & @CRLF & @CRLF)

return $result

EndFunc

Func DrawLine($fromX , $fromY , $xTo , $yTo, $width , $color )

$pic_hWnd = ControlGetHandle($gui,"" ,$graphic)

$user_dll = DllOpen("user32.dll")

$gdi_dll = DllOpen("gdi32.dll")

$l_hdc = DLLCall($user_dll,"int","GetDC","hwnd",$pic_hWnd)

$pen = DLLCall($gdi_dll,"int","CreatePen","int",0x0,"int",$width,"int",$color)

$obj_orig = DLLCall($gdi_dll,"int","SelectObject","int",$l_hdc[0],"int",$pen[0])

DLLCall($gdi_dll,"int","MoveToEx","int",$l_hdc[0],"int",$fromX,"int",$fromY,"int",0)

DLLCall($gdi_dll,"int","LineTo","int",$l_hdc[0],"int",$xTo,"int",$yTo) ;draw line

DLLCall($gdi_dll,"int","SelectObject","int",$l_hdc[0],"int",$obj_orig[0])

DLLCall($gdi_dll,"int","DeleteObject","int",$pen[0])

$l_hdc = DLLCall($user_dll,"int","ReleaseDC","hwnd",$pic_hWnd,"int",$l_hdc[0])

DllClose($gdi_dll)

DllClose($user_dll)

EndFunc

Edited by matrix200

Share this post


Link to post
Share on other sites

Look at my post here - this concept not tested but I think it should work:

$apoints = DllStructCreate("int,int,int,int,int,int") ; 3x point: X,Y
DllStructSetData($apoints, 1, 10) ; X1
DllStructSetData($apoints, 2, 11) ; Y1
DllStructSetData($apoints, 3, 20) ; X2
DllStructSetData($apoints, 4, 21) ; Y2
DllStructSetData($apoints, 5, 30) ; X3
DllStructSetData($apoints, 6, 31) ; Y3
_Polygon($hdc, DllStructGetPtr($apoints), 3)

_Polygon() is wrapper for DllCall()

Share this post


Link to post
Share on other sites

Well the function fails for some reason.

I am getting 0 as a result which means a failure according to MSDN.

The question is what kind of pointer type I should specify.

I did just "ptr" , maybe I should use some special kind of pointer?

Like long_ptr or int_ptr?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0