powerbass4

WINAPI GetLogicalProcessorInformation

12 posts in this topic

Hi, I need the help of some "C++ Pros" of you....

The "WINAPI GetLogicalProcessorInformation" function does not exists in the AutoIt Includes, so I decided to build it on my own ....no success so far.
I adapted easy functions, but this one seems to be odd and unfamiliar.

I hope somebody can help me.... and after that this function should be added to the Includes (WinAPISys.au3).

 

BOOL WINAPI GetLogicalProcessorInformation(
  _Out_   PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer,
  _Inout_ PDWORD                                ReturnLength
);

https://msdn.microsoft.com/en-us/library/windows/desktop/ms683194(v=vs.85).aspx

 

typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
  ULONG_PTR                      ProcessorMask;
  LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
  union {
    struct {
      BYTE Flags;
    } ProcessorCore;
    struct {
      DWORD NodeNumber;
    } NumaNode;
    CACHE_DESCRIPTOR Cache;
    ULONGLONG        Reserved[2];
  };
} SYSTEM_LOGICAL_PROCESSOR_INFORMATION, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686694(v=vs.85).aspx

Share this post


Link to post
Share on other sites



Moved to a more appropriate forum


√-1 2^3 ∑ π, and it was delicious!

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

maybe there is a better way to "translate" the union

#include <Array.au3>
#include <WinAPI.au3>
#include <array.au3>

#AutoIt3Wrapper_UseX64=n

;variablen zuordnen
Enum $RelationProcessorCore, _
        $RelationNumaNode, _
        $RelationCache, _
        $RelationProcessorPackage, _
        $RelationGroup, _
        $RelationAll


Global $processorCoreCount = 0, _
        $logicalProcessorCount = 0, _
        $processorPackageCount = 0, _
        $numaNodeCount = 0, _
        $L1CacheCount = 0, _
        $L2CacheCount = 0, _
        $L3CacheCount = 0, _
        $L1CacheSize = 0, _
        $L2CacheSize = 0, _
        $L3CacheSize = 0




$dll = DllOpen("kernel32.dll")
ConsoleWrite('- Debug(' & @ScriptLineNumber & ') : $dll = ' & $dll & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
ConsoleWrite('- : $dll = ' & $dll & @CRLF)               ;### Debug Console

;adresse holen
$procaddress = DllCall($dll, "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("kernel32.dll"), "str", "GetLogicalProcessorInformation")
ConsoleWrite('- : $ret = ' & $procaddress[0] & @CRLF)    ;### Debug Console

;Funktion callen, um buffer größe zu erhalten
$return_length = 0
$ret = DllCallAddress("uint", $procaddress[0], "dword", 0, "uint*", $return_length)
;~ ConsoleWrite('- : $ret = ' & $ret & @CRLF ) ;### Debug Console
$return_length = $ret[2]
;~ ConsoleWrite('- : $return_length = ' & $return_length & @CRLF ) ;### Debug Console
;~ _arraydisplay($ret)


$struct_bytes = DllStructCreate("byte [" & $return_length & "]")
$ptr = DllStructGetPtr($struct_bytes)
;~ ConsoleWrite('- : $ptr = ' & $ptr & @CRLF ) ;### Debug Console


;Funktion callen, um bufferpointer  zu übergeben und buffer zu füllen
$ret = DllCallAddress("uint", $procaddress[0], "ptr", $ptr, "uint*", $return_length)
;~ ConsoleWrite('- : $ret = ' & $ret[0] & @CRLF ) ;### Debug Console
;~ _arraydisplay($ret)

;zeig´s mir baby!!!
$ret = DllStructGetData($struct_bytes, 1)
ConsoleWrite('- : $ret = ' & ($ret) & @CRLF)             ;### Debug Console
For $i = 3 To $return_length * 2 Step 48
    $a = StringMid($ret, $i, 48)
    ConsoleWrite("    " & $a & @CRLF)
Next


ConsoleWrite(@CRLF & @CRLF & "+ Ergebnisse:" & @CRLF & @CRLF)

;zuordnen

For $i = 0 To $return_length - 24 Step 24

    $a = StringMid($ret, 3 + $i * 2, 48)
    ConsoleWrite($a & @CRLF)

;~ ;PLPI = PSYSTEM_LOGICAL_PROCESSOR_INFORMATION
    $struct_PLPI = DllStructCreate("dword ProcessorMask;" & _
            "dword Relationship;" & _
            "byte [16];", $ptr + $i)

    ;die "union" nachbasteln....alle
    $struct_Processorcore = DllStructCreate("byte Flags", DllStructGetPtr($struct_PLPI) + 8)

    $struct_NumaNode = DllStructCreate("dword NodeNumber", DllStructGetPtr($struct_PLPI) + 8)

    $struct_CACHE_DESCRIPTOR = DllStructCreate("byte Level;" & _
            "byte Associativity;" & _
            "word Linesize;" & _
            "dword Size;" & _
            "dword Type", DllStructGetPtr($struct_PLPI) + 8)



;~     $structsize = DllStructGetSize($struct_PLPI)
;~     ConsoleWrite('- : $structsize = ' & $structsize & @CRLF ) ;### Debug Console




    ;Daten auslesen
    $ProcessorMask = DllStructGetData($struct_PLPI, "ProcessorMask")
    ConsoleWrite('> $ProcessorMask = ' & $ProcessorMask & @CRLF)
    $Relationship = DllStructGetData($struct_PLPI, "Relationship")
    ConsoleWrite('> $Relationship  = ' & $Relationship)


    $Relationship = Int(DllStructGetData($struct_PLPI, "Relationship"))

    Switch $Relationship

        Case $RelationProcessorCore                      ;0 es werden Prozessor daten abgefragt
            ConsoleWrite("  ProcessorCore" & @CRLF)
            $ProcessorCore = DllStructGetData($struct_Processorcore, "Flags")
            ConsoleWrite('- : $ProcessorCore = ' & $ProcessorCore & @CRLF) ;### Debug Console

            $processorCoreCount += 1

            $logicalProcessorCount += CountSetBits($ProcessorMask)

        Case $RelationNumaNode
            ConsoleWrite("  NumaNode" & @CRLF)
            $NodeNumber = DllStructGetData($struct_NumaNode, "NodeNumber")
            ConsoleWrite('- : $NodeNumber = ' & $NodeNumber & @CRLF) ;### Debug Console

            $numaNodeCount += 1

        Case $RelationCache
            ConsoleWrite("  RelationCache" & @CRLF)
            $Level = DllStructGetData($struct_CACHE_DESCRIPTOR, "Level")
            ConsoleWrite('- : $Level = ' & $Level & @CRLF) ;### Debug Console
            $Associativity = DllStructGetData($struct_CACHE_DESCRIPTOR, "Associativity")
            ConsoleWrite('- : $Associativity = ' & $Associativity & @CRLF) ;### Debug Console
            $Linesize = DllStructGetData($struct_CACHE_DESCRIPTOR, "Linesize")
            ConsoleWrite('- : $Linesize = ' & $Linesize & @CRLF) ;### Debug Console
            $Size = DllStructGetData($struct_CACHE_DESCRIPTOR, "Size")
            ConsoleWrite('- : $Size = ' & $Size & @CRLF) ;### Debug Console
            $Type = DllStructGetData($struct_CACHE_DESCRIPTOR, "Type")
            ConsoleWrite('- : $Type = ' & $Type & @CRLF) ;### Debug Console

            Switch $Level
                Case 1
                    $L1CacheCount += 1
                    $L1CacheSize += $Size
                Case 2
                    $L2CacheCount += 1
                    $L2CacheSize += $Size
                Case 3
                    $L3CacheCount += 1
                    $L3CacheSize += $Size
            EndSwitch




        Case $RelationProcessorPackage
            ConsoleWrite("  ProcessorPackage" & @CRLF)
            $processorPackageCount += 1

        Case $RelationGroup
            ConsoleWrite("  Group" & @CRLF)



    EndSwitch






    ConsoleWrite(@CRLF & @CRLF)

Next



$returnstring = "GetLogicalProcessorInformation:" & @CRLF & @CRLF & _
        StringFormat("Number %-30s = %u", "Processorcores", $processorCoreCount) & @CRLF & _
        StringFormat("Number %-30s = %u", "NumaNodes", $numaNodeCount) & @CRLF & _
        StringFormat("Number %-30s = %u", "logicalProcessorCount", $logicalProcessorCount) & @CRLF & _
        StringFormat("Number %-30s = %u", "processorPackageCount", $processorPackageCount) & @CRLF & _
        StringFormat("Number %-30s = %u/%u/%u", "Level1/2/3-Caches", $L1CacheCount, $L2CacheCount, $L3CacheCount) & @CRLF & _
        StringFormat("Number %-30s = %u/%u/%u", "L1/L2/L3 cache sizes (kB)", $L1CacheSize / 1024, $L2CacheSize / 1024, $L3CacheSize / 1024) & @CRLF & _
        ""

ConsoleWrite($returnstring & @CRLF)

MsgBox(0, "GetLogicalProcessorInformation", $returnstring)



Func CountSetBits($uint)                                 ;zählt gesetzte bits
    $anz = 0
    For $i = 0 To 31
        If BitAND(2 ^ $i, $uint) Then $anz += 1
    Next
    Return $anz
EndFunc                                                  ;==>CountSetBits

 

Edited by AndyG

Share this post


Link to post
Share on other sites

Thanks again Andy !

 

Maybe someone will optimize it and give it to the AutoIt devs....:thumbsup:

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

@AndyG: Hi! Please, can you be so kind to explain me these two issues:

Quote
For $i = 0 To $return_length - 48 Step 24

 

Why do you exclude last 48 bytes?

Quote
$a = StringMid($ret, 3 + $i * 2, 48)

 

Why do you exclude first 3 bytes and $i is multiplied by 2?

 

Edited by j0kky

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

@j0kky,

Because I can not program (only "read" a little bit) C(++)-code, i had to examine those "UNION"-stuff.

The "showing" of the bytes in several "lines" helped me to understand the structure, so i converted the bytes to chars to have a better "view" into the data!

The SYSTEM_LOGICAL_PROCESSOR_INFORMATION - struct has a lenght of 24bytes. In HEX-representation, the length is 48 chars....the length of the entire string is 2 (chars/bytes) for the "0x" and X*48(chars/bytes). The data starts at the third character, the first 2 are the "0x".

Imagine, that the 24Byte-SYSTEM_LOGICAL_PROCESSOR_INFORMATION - struct is a "Window"  to show only 24Bytes in the memory from all the bytes given back from the GetLogicalProcessorInformation-Function-call.

The start-address for every "24-bytes-Window" is the pointer to the memory plus 24 Bytes....

If you reach the end, the last "24-bytes-Window" is the region/area 24 bytes in front of the last byte....in HEX-reperesentation 48 chars. The last "address" for stringmid() to show the next(last) 48 chars is (endaddress-48).

I hope that i could clarify a little bit and that my explanations were useful. If not, ask again and surely someone with a much better phrasing/mode of expression than me will help you!

 

[OT]What should I do without google translate:>[OT]

 

code for 32/64Bit

#include <Array.au3>
#include <WinAPI.au3>


#AutoIt3Wrapper_UseX64=y                                 ;für 32/64Bit

;variablen zuordnen
Enum $RelationProcessorCore, _
        $RelationNumaNode, _
        $RelationCache, _
        $RelationProcessorPackage, _
        $RelationGroup, _
        $RelationAll


Global $processorCoreCount = 0, _
        $logicalProcessorCount = 0, _
        $processorPackageCount = 0, _
        $numaNodeCount = 0, _
        $L1CacheCount = 0, _
        $L2CacheCount = 0, _
        $L3CacheCount = 0, _
        $L1CacheSize = 0, _
        $L2CacheSize = 0, _
        $L3CacheSize = 0


If @AutoItX64 Then
    $32_64 = 32
    $sSize = 16
Else
    $32_64 = 24
    $sSize = 8
EndIf



$dll = DllOpen("kernel32.dll")
;~ ConsoleWrite('- Debug(' & @ScriptLineNumber & ') : $dll = ' & $dll & @CRLF & '>Error code: ' & @error & @CRLF) ;### Debug Console
;~ ConsoleWrite('- : $dll = ' & $dll & @CRLF)               ;### Debug Console

;adresse holen
$procaddress = DllCall($dll, "ptr", "GetProcAddress", "ptr", _WinAPI_GetModuleHandle("kernel32.dll"), "str", "GetLogicalProcessorInformation")
;~ ConsoleWrite('- : $ret = ' & $procaddress[0] & @CRLF)    ;### Debug Console

;Funktion callen, um buffer größe zu erhalten
$return_length = 0
$ret = DllCallAddress("uint", $procaddress[0], "dword", 0, "uint*", $return_length)
;~ ConsoleWrite('- : $ret = ' & $ret & @CRLF ) ;### Debug Console
$return_length = $ret[2]
;~ ConsoleWrite('- : $return_length = ' & $return_length & @CRLF ) ;### Debug Console
;~ _ArrayDisplay($ret)


$struct_bytes = DllStructCreate("byte [" & $return_length & "]")
$ptr = DllStructGetPtr($struct_bytes)
;~ ConsoleWrite('- : $ptr = ' & $ptr & @CRLF ) ;### Debug Console


;Funktion callen, um bufferpointer  zu übergeben und buffer zu füllen
$ret = DllCallAddress("uint", $procaddress[0], "ptr", $ptr, "uint*", $return_length)
;~ ConsoleWrite('- : $ret = ' & $ret[0] & @CRLF ) ;### Debug Console
;~ _arraydisplay($ret)

;zeig´s mir baby!!!
$ret = DllStructGetData($struct_bytes, 1)
ConsoleWrite('- : $ret = ' & ($ret) & @CRLF)             ;### Debug Console
For $i = 3 To $return_length * 2 Step $32_64 * 2
    $a = StringMid($ret, $i, $32_64 * 2)
    ConsoleWrite("    " & $a & @CRLF)
Next


ConsoleWrite(@CRLF & @CRLF & "+ Ergebnisse:" & @CRLF & @CRLF)

;zuordnen

For $i = 0 To $return_length - $32_64 Step $32_64

    $a = StringMid($ret, 3 + $i * 2, $32_64 * 2)
    ConsoleWrite($a & @CRLF)

;~ ;PLPI = PSYSTEM_LOGICAL_PROCESSOR_INFORMATION
    $struct_PLPI = DllStructCreate("uint_ptr ProcessorMask;" & _
            "uint_ptr Relationship;" & _
            "byte [" & $32_64 - 16 & "]", $ptr + $i)

    ;die "union" nachbasteln....alle
    $struct_Processorcore = DllStructCreate("byte Flags", DllStructGetPtr($struct_PLPI) + $sSize)

    $struct_NumaNode = DllStructCreate("dword NodeNumber", DllStructGetPtr($struct_PLPI) + $sSize)

    $struct_CACHE_DESCRIPTOR = DllStructCreate("byte Level;" & _
            "byte Associativity;" & _
            "word Linesize;" & _
            "dword Size;" & _
            "dword Type", DllStructGetPtr($struct_PLPI) + $sSize)



;~     $structsize = DllStructGetSize($struct_PLPI)
;~     ConsoleWrite('- : $structsize = ' & $structsize & @CRLF ) ;### Debug Console




    ;Daten auslesen
    $ProcessorMask = DllStructGetData($struct_PLPI, "ProcessorMask")
    ConsoleWrite('> $ProcessorMask = ' & $ProcessorMask & @CRLF)
    $Relationship = DllStructGetData($struct_PLPI, "Relationship")
    ConsoleWrite('> $Relationship  = ' & $Relationship)


    $Relationship = Int(DllStructGetData($struct_PLPI, "Relationship"))

    Switch $Relationship

        Case $RelationProcessorCore                      ;0 es werden Prozessor daten abgefragt
            ConsoleWrite("  ProcessorCore" & @CRLF)
            $ProcessorCore = DllStructGetData($struct_Processorcore, "Flags")
            ConsoleWrite('- : $ProcessorCore = ' & $ProcessorCore & @CRLF) ;### Debug Console

            $processorCoreCount += 1

            $logicalProcessorCount += CountSetBits($ProcessorMask)

        Case $RelationNumaNode
            ConsoleWrite("  NumaNode" & @CRLF)
            $NodeNumber = DllStructGetData($struct_NumaNode, "NodeNumber")
            ConsoleWrite('- : $NodeNumber = ' & $NodeNumber & @CRLF) ;### Debug Console

            $numaNodeCount += 1

        Case $RelationCache
            ConsoleWrite("  RelationCache" & @CRLF)
            $Level = DllStructGetData($struct_CACHE_DESCRIPTOR, "Level")
            ConsoleWrite('- : $Level = ' & $Level & @CRLF) ;### Debug Console
            $Associativity = DllStructGetData($struct_CACHE_DESCRIPTOR, "Associativity")
            ConsoleWrite('- : $Associativity = ' & $Associativity & @CRLF) ;### Debug Console
            $Linesize = DllStructGetData($struct_CACHE_DESCRIPTOR, "Linesize")
            ConsoleWrite('- : $Linesize = ' & $Linesize & @CRLF) ;### Debug Console
            $Size = DllStructGetData($struct_CACHE_DESCRIPTOR, "Size")
            ConsoleWrite('- : $Size = ' & $Size & @CRLF) ;### Debug Console
            $Type = DllStructGetData($struct_CACHE_DESCRIPTOR, "Type")
            ConsoleWrite('- : $Type = ' & $Type & @CRLF) ;### Debug Console

            Switch $Level
                Case 1
                    $L1CacheCount += 1
                    $L1CacheSize += $Size
                Case 2
                    $L2CacheCount += 1
                    $L2CacheSize += $Size
                Case 3
                    $L3CacheCount += 1
                    $L3CacheSize += $Size
            EndSwitch




        Case $RelationProcessorPackage
            ConsoleWrite("  ProcessorPackage" & @CRLF)
            $processorPackageCount += 1

        Case $RelationGroup
            ConsoleWrite("  Group" & @CRLF)



    EndSwitch






    ConsoleWrite(@CRLF & @CRLF)

Next



$returnstring = "GetLogicalProcessorInformation: " & 32 * (1 + @AutoItX64) & "Bit" & @CRLF & @CRLF & _
        StringFormat("Number %-30s = %u", "Processorcores", $processorCoreCount) & @CRLF & _
        StringFormat("Number %-30s = %u", "NumaNodes", $numaNodeCount) & @CRLF & _
        StringFormat("Number %-30s = %u", "logicalProcessorCount", $logicalProcessorCount) & @CRLF & _
        StringFormat("Number %-30s = %u", "processorPackageCount", $processorPackageCount) & @CRLF & _
        StringFormat("Number %-30s = %u/%u/%u", "Level1/2/3-Caches", $L1CacheCount, $L2CacheCount, $L3CacheCount) & @CRLF & _
        StringFormat("Number %-30s = %u/%u/%u", "L1/L2/L3 cache sizes (kB)", $L1CacheSize / 1024, $L2CacheSize / 1024, $L3CacheSize / 1024) & @CRLF & _
        ""

ConsoleWrite($returnstring & @CRLF)

MsgBox(0, "GetLogicalProcessorInformation", $returnstring)



Func CountSetBits($uint)                                 ;zählt gesetzte bits
    $anz = 0
    For $i = 0 To 31
        If BitAND(2 ^ $i, $uint) Then $anz += 1
    Next
    Return $anz
EndFunc                                                  ;==>CountSetBits

 

 

 

Edited by AndyG

Share this post


Link to post
Share on other sites

You have been extremely clear, my mistake was not to consider what DllStructGetData does to binary data (it multiplies by 2 the final lenght and adds 2 characters "0x" at the start) :D

Thank you very much!

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

@Andy G: On second thought I'm quite sure in first script it should be:

For $i = 0 To $return_length - 24 Step 24

In fact, in my system, if you exclude 48 bytes instead of 24, you don't count a NumaNode!

Edited by j0kky

Share this post


Link to post
Share on other sites

You are right, thank you very much!:thumbsup:

I´ll edit the scripts...

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

2 hours ago, j0kky said:

I don't know if GetProcAddress involvement is really necessary!

No, it´s not!

"Stolen" from chesstiger´s not fully working try :bye::

$hDll = DllOpen("Kernel32.dll")
    $tBufferSize = DllStructCreate("dword size;")
    DllCall($hDll, "bool", "GetLogicalProcessorInformation", "struct*", 0, "DWORD_PTR", DllStructGetPtr($tBufferSize, "size"))
    $hMem = _MemGlobalAlloc($tBufferSize.size, $GPTR) ;Nötig, da sonst nach Verlassen der Funktion der Speicherbereich freigegeben wird...
    $tBuffer = DllStructCreate("byte[" & $tBufferSize.size & "]", $hMem)
    DllCall($hDll, "bool", "GetLogicalProcessorInformation", "struct*", DllStructGetPtr($tBuffer), "DWORD_PTR", DllStructGetPtr($tBufferSize, "size"))

this and the use of something like an OO-Style (to get the content of the structs by their name like $buffer.item ) should lead to a good result. Have fun!

Edited by AndyG

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

  • Similar Content

    • NHD
      By NHD
      Hi,
      I've been translated code from FreeBasic to AutoIt. And it didn't work correctly.
      Please help me!
      FreeBasic:
      #Include Once "windows.bi" #Define _RGB(r,g,b) BGR(b,g,r) CONST GRADIENT_FILL_RECT_H = 0 CONST GRADIENT_FILL_RECT_V = 1 Dim Shared hInstance As HINSTANCE ' This dll is located in Windows directory DECLARE FUNCTION Gradientfill Lib "MSIMG32" ALIAS "GradientFill" _ (hDC AS HDC, pVertex As PTRIVERTEX, dwNumVertex As Integer,pMesh AS PGRADIENT_RECT, dwNumMesh As Integer, dwMode As Integer) As Integer '******************************************************************** ' A FB Control Template '******************************************************************** Declare Function NiceButt(ByVal hWnd as HWND,byval Msg as UINT,byval wParam as WPARAM,byval lParam as LPARAM) as LRESULT Declare FUNCTION IsMouseOver (hWnd As HWND )As Integer Declare SUB Draw_Gradient (hdc as HDC, x As Integer, y As integer, w As integer, h As Integer, r As integer, g As integer, b As integer) Declare FUNCTION Register_NiceButt()As Integer ' 'Windows calls this function when the dll is loaded. /'Function DllMain alias "MAIN"(byval hModule as HMODULE,byval reason as Integer,byval lpReserved as LPVOID) as BOOL Select case reason case DLL_PROCESS_ATTACH hInstance=hModule Register_NiceButt() MessageBox(GetActiveWindow(),"OK","OK",MB_OK) Return 0 case DLL_PROCESS_DETACH ' end select return TRUE end function '/ FUNCTION Register_NiceButt()As Integer Export DIM wc AS WNDCLASSEX DIM szClassName As String szClassName = "NiceButt" wc.cbSize = SIZEOF(WNDCLASSEX) wc.style = CS_HREDRAW OR CS_VREDRAW OR CS_GLOBALCLASS wc.hInstance = GetmoduleHandle(0) 'hInstance wc.hbrBackground = Cast(HBRUSH,COLOR_BTNFACE+1) wc.lpszClassName = StrPtr(szClassName) wc.lpfnWndProc = @NiceButt wc.cbClsExtra = 0 wc.cbWndExtra = 0 wc.hIcon = 0 wc.hCursor = 0 wc.lpszMenuName = 0 wc.hIconSm = 0 FUNCTION = RegisterClassEx(@wc) END FUNCTION '******************************************************************** ' Custom Control Procedure '******************************************************************** Function NiceButt(ByVal hWnd as HWND,byval Msg as UINT,byval wParam as WPARAM,byval lParam as LPARAM) as LRESULT STATIC As Integer ButtDown,mouseover STATIC Captured AS HWND SELECT Case Msg '************************** CASE WM_CREATE '************************** DIM Region AS HRGN DIM Rct AS RECT DIM As Integer x, y, w, h ButtDown = FALSE GetClientRect (hWnd,@Rct) ' <<-- Get the size of our control x = Rct.left y = Rct.top w = Rct.right - Rct.left h = Rct.bottom - Rct.top 'Region = CreateRoundRectRgn(10,10,w,h, h * 0.90 , h * 0.90 ) 'SetWindowRgn (hWnd,Region,True) InvalidateRect(hWnd,0,0) 'EXIT FUNCTION ' ******************* CASE WM_PAINT ' ******************* DIM hDC AS HDC DIM ps AS PAINTSTRUCT DIM hPen AS HPEN DIM hBrush AS HBRUSH DIM hOldBrush AS HBRUSH DIM Rct AS RECT DIM Size AS SIZE DIM T As ZString*2048 DIM As Integer i DIM As Integer XCtr DIM As Integer YCtr DIM As Integer x,y,w,h DIM As Integer r,g,b ' ******************* GetClientRect (hWnd,@Rct) ' <<-- Get the size of our control x = Rct.left y = Rct.top w = Rct.right - Rct.left h = Rct.bottom - Rct.top XCtr = (Rct.left + Rct.right) / 2 ' Horizontal center of our ctrl YCtr = (Rct.top + Rct.bottom) / 2 ' Vertical center of our ctrl GetWindowText(hWnd,T ,255) ' Grab a copy of control caption '********************************** ' Draw our control '********************************** hDC = BeginPaint (hWnd, @ps) GetTextExtentPoint32(hDC, T , LEN(T),@Size) ' Get caption size r = 30 : g = 90 : b = 90 Draw_Gradient (hDC, x, y, w, h, r, g, b) SetBkMode (hDC,TRANSPARENT) IF ButtDown THEN SetTextColor(hDC,_RGB(255,0,0)) TextOut(hDC, XCtr-(Size.cx/2)+1, YCtr-(Size.cy/2)+1,T,LEN(T)) ELSE SetTextColor(hDC,_RGB(0,0,255)) TextOut(hDC, XCtr-Size.cx/2, YCtr-Size.cy/2,T,LEN(T)) END IF EndPaint (hWnd,@ps) 'EXIT FUNCTION '****************************** CASE WM_LBUTTONUP '****************************** IF hWnd = Captured THEN DIM hParent AS HWND ReleaseCapture() ButtDown = FALSE InvalidateRect(hWnd,0,0) hParent=GetParent(hWnd) SendMessage(hParent,WM_COMMAND,MAKELONG(GetWindowLong(hWnd,GWL_ID), BN_CLICKED),Cast(LONG,hWnd)) END IF 'EXIT FUNCTION '****************************** CASE WM_LBUTTONDOWN '****************************** SetCapture(hWnd) Captured = hWnd ButtDown = TRUE SetFocus (hWnd) InvalidateRect(hWnd,0,0) 'EXIT FUNCTION '****************************** CASE WM_MOUSEMOVE '****************************** IF ButtDown THEN IF IsMouseOver(hWnd) THEN ButtDown = TRUE InvalidateRect(hWnd,0,0) ELSE ReleaseCapture() ButtDown = FALSE InvalidateRect(hWnd,0,0) END IF END IF 'EXIT FUNCTION '****************************** CASE WM_MOVING '****************************** ReleaseCapture() ButtDown = FALSE InvalidateRect(hWnd,0,0) 'EXIT FUNCTION '****************************** CASE WM_SIZE '****************************** ReleaseCapture() ButtDown = FALSE InvalidateRect(hWnd,0,0) 'EXIT FUNCTION END Select Return DefWindowProc(hwnd,Msg,wparam,lparam) END FUNCTION SUB Draw_Gradient (hdc as HDC, x As Integer, y As integer, w As integer, h As Integer, r As integer, g As integer, b As integer) DIM Vert(2) AS TRIVERTEX DIM Rect AS GRADIENT_RECT '****************************************************** Vert (0).x = 0 Vert (0).y = 0 Vert (0).Red = 65535-(65535-(r*256)) Vert (0).Green = 65535-(65535-(g*256)) Vert (0).Blue = 65535-(65535-(b*256)) Vert (0).Alpha = 0 '****************************************************** Vert (1).x = w Vert (1).y = h/2 Vert (1).Red = 65535-(65535-(255*256)) Vert (1).Green = 65535-(65535-(255*256)) Vert (1).Blue = 65535-(65535-(255*256)) Vert (1).Alpha = 0 '****************************************************** Rect.UpperLeft = 0 Rect.LowerRight = 1 '****************************************************** Gradientfill(hdc,@Vert(0),2,@Rect,1,GRADIENT_FILL_RECT_V) '****************************************************** Vert (0).x = 0 Vert (0).y = h/2 Vert (0).Red = 65535-(65535-(255*256)) Vert (0).Green = 65535-(65535-(255*256)) Vert (0).Blue = 65535-(65535-(255*256)) Vert (0).Alpha = 0 '****************************************************** Vert (1).x = w Vert (1).y = h Vert (1).Red = 65535-(65535-(r*256)) Vert (1).Green = 65535-(65535-(g*256)) Vert (1).Blue = 65535-(65535-(b*256)) Vert (1).Alpha = 0 '****************************************************** Rect.UpperLeft = 0 Rect.LowerRight = 1 '****************************************************** Gradientfill(hdc,@Vert(0),2,@Rect,1,GRADIENT_FILL_RECT_V) END SUB FUNCTION IsMouseOver (hWnd As HWND )As Integer DIM Rect As RECT DIM Pt As POINT GetWindowRect (hWnd, @Rect) GetCursorPos(@Pt) FUNCTION = PtInRect (@Rect, Pt) END FUNCTION  
      AutoIt:
      #include-once #include <WinAPI.au3> #include <WinAPIGdi.au3> #include <WinAPISys.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> ;~ #Include <windows.bi> Global Const $_tagRect = "struct;long left;long top;long right;long bottom;endstruct" Global Const $_tagSize = "struct;long cx;long cy;endstruct" Global Const $_tagGradient_Rect = "struct;ulong UpperLeft;ulong LowerRight;endstruct" Global Const $_tagPoint = "struct;long x;long y;endstruct" Global Const $_tagTrivertex = "struct;long x;long y;int Red;int Greed;int Blue;int Alpha;endstruct" Global Const $_tagPaintStruct = "struct;handle hdc;bool fErase;long left;long top;long right;long bottom;bool fRestore;bool fIncUpdate;byte rgbReserved[32];endstruct" Global Const $_tagWNDCLASSEX = "struct;uint cbSize;uint style;ptr lpfnWndProc;int cbClsExtra;int cbWndExtra;ptr hInstance;ptr hIcon;" & _ "ptr hCursor; ptr hbrBackground; ptr lpszMenuName;ptr lpszClassName;ptr hIconSm;endstruct" Global Const $CS_VREDRAW = 0x0001, $CS_HREDRAW =0x0002, $CS_GLOBALCLASS = 0x4000 Global Const $BN_CLICKED = 0 ;~ #Define _RGB(r,g,b) BGR(b,g,r) Global Const $GRADIENT_FILL_RECT_H = 0 Global Const $GRADIENT_FILL_RECT_V = 1 ;~ Dim Shared hInstance As HINSTANCE ;~ ' This dll is located in Windows directory ;~ DECLARE FUNCTION Gradientfill Lib "MSIMG32" ALIAS "GradientFill" _ ;~ (hDC AS HDC, pVertex As PTRIVERTEX, dwNumVertex As Integer,pMesh AS PGRADIENT_RECT, dwNumMesh As Integer, dwMode As Integer) As Integer ;~ '******************************************************************** ;~ ' A FB Control Template ;~ '******************************************************************** ;~ Declare Function NiceButt(ByVal hWnd as HWND,byval Msg as UINT,byval wParam as WPARAM,byval lParam as LPARAM) as LRESULT ;~ Declare FUNCTION IsMouseOver (hWnd As HWND )As Integer ;~ Declare SUB Draw_Gradient (hdc as HDC, x As Integer, y As integer, w As integer, h As Integer, r As integer, g As integer, b As integer) ;~ Declare FUNCTION Register_NiceButt()As Integer #cs ' 'Windows calls this function when the dll is loaded. /'Function DllMain alias "MAIN"(byval hModule as HMODULE,byval reason as Integer,byval lpReserved as LPVOID) as BOOL Select case reason case DLL_PROCESS_ATTACH hInstance=hModule Register_NiceButt() MessageBox(GetActiveWindow(),"OK","OK",MB_OK) Return 0 case DLL_PROCESS_DETACH ' end select return True end function '/ #ce #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 615, 437, 192, 124) RegisterButton() Global $Ctrl = _winapi_CreateWindowEx(0, "TestButton", "Test", BitOR($WS_VISIBLE, $WS_CHILD), 10, 10, 80, 30, $Form1) ConsoleWrite(@CRLF & $Ctrl) GUISetState(@SW_SHOW) _WinAPI_UpdateWindow($Form1) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Func RegisterButton() Local $hDll = DllCallbackRegister('TestButtonProc', 'lresult', 'hwnd;uint;wparam;lparam') ;~ DIM wc AS WNDCLASSEX ;~ DIM szClassName As String Local $sClass = "TestButton" Local $wc = DllStructCreate($_tagWNDCLASSEX & ';wchar szClassName[' & (StringLen($sClass) + 1) & ']') ;~ szClassName = "NiceButt" ;~ wc.cbSize = SIZEOF(WNDCLASSEX) $wc.cbSize = DllStructGetPtr($wc, 'szClassName') - DllStructGetPtr($wc) ;~ wc.style = CS_HREDRAW OR CS_VREDRAW OR CS_GLOBALCLASS $wc.style = BitOR($CS_HREDRAW, $CS_VREDRAW, $CS_GLOBALCLASS) ;~ wc.hInstance = GetmoduleHandle(0) 'hInstance $wc.hInstance = _WinAPI_GetModuleHandle(0) ;~ wc.hbrBackground = Cast(HBRUSH,COLOR_BTNFACE+1) ;/// $wc.hbrBackground = _WinAPI_CreateSolidBrush(_WinAPI_GetSysColor($COLOR_BTNFACE)) ;~ wc.lpszClassName = StrPtr(szClassName) $wc.lpszClassName = DllStructGetPtr($wc, 'szClassName') ;~ wc.lpfnWndProc = @NiceButt $wc.lpfnWndProc = DllCallbackGetPtr($hDll) ;~ wc.cbClsExtra = 0 $wc.cbClsExtra = 0 ;~ wc.cbWndExtra = 0 $wc.cbWndExtra = 0 ;~ wc.hIcon = 0 $wc.hIcon = 0 ;~ wc.hCursor = 0 $wc.hCursor = 0 ;~ wc.lpszMenuName = 0 $wc.lpszMenuName = 0 ;~ wc.hIconSm = 0 $wc.hIconSm = 0 $wc.szClassName = $sClass ;~ FUNCTION = RegisterClassEx(@wc) Local $aRet = _WinAPI_RegisterClassEx($wc) Return $aRet ;~ END FUNCTION EndFunc ;******************************************************************** ; Custom Control Procedure ;******************************************************************** ;~ Function NiceButt(ByVal hWnd as HWND,byval Msg as UINT,byval wParam as WPARAM,byval lParam as LPARAM) as LRESULT Func TestButtonProc($hWnd, $iMsg, $wParam, $lParam) Static $bBtnDown, $bMouseOver, $hCaptured Switch $iMsg Case $WM_CREATE Local $Rct = DllStructCreate($_tagRect) Local $iX, $iY, $iW, $iH $bBtnDown = False GetClientRect($hWnd, $Rct) $iX = $Rct.left $iY = $Rct.top $iW = $Rct.right - $Rct.left $iH = $Rct.bottom - $Rct.top InvalidateRect($hWnd, 0, False) ;~ EXIT FUNCTION ;~ Return 0 Case $WM_PAINT Local $ps ;= DllStructCreate($_tagPaintStruct) Local $hPen, $hBrush, $hOldBrush Dim $Rct = DllStructCreate($_tagRect) Dim $Size = DllStructCreate($_tagSize) Dim $T = "", $i Dim $XCtr, $YCtr Dim $iX, $iY, $iW, $iH Dim $iR, $iG, $iB GetClientRect($hWnd, $Rct) $iX = $Rct.left $iY = $Rct.top $iW = $Rct.right - $Rct.left $iH = $Rct.bottom - $Rct.top $XCtr = ($Rct.left + $Rct.right) / 2 $YCtr = ($Rct.top + $Rct.bottom) / 2 ;~ GetWindowText(hWnd,T ,255) ' Grab a copy of control caption ;~ DllCall("user32.dll", "int", "GetWindowTextW", "hwnd", $hWnd, "LPTSTR ", $T, "int", 255) ; not work $T = "Test" ;********************************** ; Draw our control ;********************************** Local $hDC = BeginPaint($hWnd, $ps) ;~ GetTextExtentPoint32(hDC, T , LEN(T),@Size) ' Get caption size GetTextExtentPoint32($hDC, $T, StringLen($T), $Size) $iR = 30 $iG = 90 $iB = 90 Draw_Gradient($hDC, $iX, $iY, $iW, $iH, $iR, $iG, $iB) SetBkMode($hDC, $TRANSPARENT) If $bBtnDown Then ;~ SetTextColor(hDC,_RGB(255,0,0)) SetTextColor($hDC, Dec(0xFF0000)) TextOut($hDC, $XCtr-($Size.cx/2)+1, $YCtr-($Size.cy/2)+1, $T) Else ;~ SetTextColor(hDC,_RGB(0,0,255)) SetTextColor($hDC, Dec(0x0000FF)) TextOut($hDC, $XCtr-$Size.cx/2, $YCtr-$Size.cy/2, $T) EndIf EndPaint($hWnd, $ps) ;~ EXIT FUNCTION ;~ Return 0 Case $WM_LBUTTONUP If $hWnd = $hCaptured Then ReleaseCapture() $bBtnDown = False InvalidateRect($hWnd, 0, 0) Local $hParent = GetParent($hWnd) ;~ SendMessage(hParent,WM_COMMAND,MAKELONG(GetWindowLong(hWnd,GWL_ID), BN_CLICKED),Cast(LONG,hWnd)) DllCall("user32.dll", "LRESULT", "SendMessageW", _ "hwnd", $hParent, _ "uint", $WM_COMMAND, _ "WPARAM", _WinAPI_MakeLong(_WinAPI_GetWindowLong($hWnd, $GWL_ID), $BN_CLICKED), _ "LPARAM", $hWnd) EndIf ;~ EXIT FUNCTION Return 0 Case $WM_LBUTTONDOWN SetCapture($hWnd) $hCaptured = $hWnd $bBtnDown = True SetFocus($hWnd) InvalidateRect($hWnd, 0, False) ;~ EXIT FUNCTION Return 0 Case $WM_MOUSEMOVE If $bBtnDown Then If IsMouseOver($hWnd) Then $bBtnDown = True InvalidateRect($hWnd, 0, False) ELSE ReleaseCapture() $bBtnDown = False InvalidateRect($hWnd, 0, False) EndIf EndIf ;~ EXIT FUNCTION ;~ Return 0 Case $WM_MOVING ReleaseCapture() $bBtnDown = False InvalidateRect($hWnd, 0, False) ;~ EXIT FUNCTION ;~ Return 0 Case $WM_SIZE ReleaseCapture() $bBtnDown = False InvalidateRect($hWnd, 0, False) ;~ EXIT FUNCTION ;~ Return 0 EndSwitch ;~ Return _WinAPI_DefWindowProc($hWnd, $iMsg, $wParam, $lParam) Return DllCall("user32.dll", "lresult", "DefWindowProcW", "hwnd", $hWnd, "uint", $iMsg, "wparam", $wParam, _ "lparam", $lParam)[0] EndFunc ;~ SUB Draw_Gradient (hdc as HDC, x As Integer, y As integer, w As integer, h As Integer, r As integer, g As integer, b As integer) Func Draw_Gradient($hDC, $iX, $iY, $iW, $iH, $iR, $iG, $iB) ;~ DIM Vert(2) AS TRIVERTEX Local $Vert[2] $Vert[0] = DllStructCreate($_tagTrivertex) $Vert[1] = DllStructCreate($_tagTrivertex) ;~ DIM Rect AS GRADIENT_RECT Local $Rect = DllStructCreate($_tagGradient_Rect) ;~ Vert (0).x = 0 $Vert[0].x = 0 ;~ Vert (0).y = 0 $Vert[0].y = 0 ;~ Vert (0).Red = 65535-(65535-(r*256)) $Vert[0].Red = 65535-(65535-($iR*256)) ;~ Vert (0).Green = 65535-(65535-(g*256)) $Vert[0].Green = 65535-(65535-($iG*256)) ;~ Vert (0).Blue = 65535-(65535-(b*256)) $Vert[0].Blue = 65535-(65535-($iB*256)) ;~ Vert (0).Alpha = 0 $Vert[0].Alpha = 0 ;~ '****************************************************** ;~ Vert (1).x = w $Vert[1].x = $iW ;~ Vert (1).y = h/2 $Vert[1].y = $iH/2 ;~ Vert (1).Red = 65535-(65535-(255*256)) $Vert[1].Red = 65535-(65535-(255*256)) ;~ Vert (1).Green = 65535-(65535-(255*256)) $Vert[1].Green = 65535-(65535-(255*256)) ;~ Vert (1).Blue = 65535-(65535-(255*256)) $Vert[1].Blue = 65535-(65535-(255*256)) ;~ Vert (1).Alpha = 0 $Vert[1].Alpha = 0 ;~ '****************************************************** ;~ Rect.UpperLeft = 0 $Rect.UpperLeft = 0 ;~ Rect.LowerRight = 1 $Rect.LowerRight = 1 ;~ '****************************************************** ;~ Gradientfill(hdc,@Vert(0),2,@Rect,1,GRADIENT_FILL_RECT_V) GradientFill($hDC, $Vert[0], 2, $Rect, 1, $GRADIENT_FILL_RECT_V) ;~ '****************************************************** ;~ Vert (0).x = 0 $Vert[0].x = 0 ;~ Vert (0).y = h/2 $Vert[0].y = $iH/2 ;~ Vert (0).Red = 65535-(65535-(255*256)) $Vert[0].Red = 65535-(65535-(255*256)) ;~ Vert (0).Green = 65535-(65535-(255*256)) $Vert[0].Green = 65535-(65535-(255*256)) ;~ Vert (0).Blue = 65535-(65535-(255*256)) $Vert[0].Blue = 65535-(65535-(255*256)) ;~ Vert (0).Alpha = 0 $Vert[0].Alpha = 0 ;~ '****************************************************** ;~ Vert (1).x = w $Vert[1].x = $iW ;~ Vert (1).y = h $Vert[1].y = $iH ;~ Vert (1).Red = 65535-(65535-(r*256)) $Vert[1].Red = 65535-(65535-($iR*256)) ;~ Vert (1).Green = 65535-(65535-(g*256)) $Vert[1].Green = 65535-(65535-($iG*256)) ;~ Vert (1).Blue = 65535-(65535-(b*256)) $Vert[1].Blue = 65535-(65535-($iB*256)) ;~ Vert (1).Alpha = 0 $Vert[1].Alpha = 0 ;~ '****************************************************** ;~ Rect.UpperLeft = 0 $Rect.UpperLeft = 0 ;~ Rect.LowerRight = 1 $Rect.LowerRight = 1 ;~ '****************************************************** ;~ Gradientfill(hdc,@Vert(0),2,@Rect,1,GRADIENT_FILL_RECT_V) GradientFill($hDC, $Vert[0], 2, $Rect, 1, $GRADIENT_FILL_RECT_V) ;~ END SUB EndFunc Func IsMouseOver($hWnd) Local $Rect = DllStructCreate($_tagRect) Local $Pt = DllStructCreate($_tagPoint) GetWindowRect ($hWnd, $Rect) GetCursorPos($Pt) Return PtInRect($Rect, $Pt) EndFunc Func _RGB($iR, $iG, $iB) Return ('0x' & Hex($iR, 2) & Hex($iG, 2) & Hex($iB, 2)) EndFunc Func _BGR($iB, $iG, $iR) Return ('0x' & Hex($iB, 2) & Hex($iG, 2) & Hex($iR, 2)) EndFunc Func InvalidateRect($hWnd, $tRECT = 0, $bErase = True) DllCall("user32.dll", "bool", "InvalidateRect", "hwnd", $hWnd, "struct*", $tRECT, "bool", $bErase) EndFunc Func SetFocus($hWnd) DllCall("user32.dll", "hwnd", "SetFocus", "hwnd", $hWnd) EndFunc Func PtInRect($tRect, $tPoint) Local $aRet = DllCall("user32.dll", "bool", "PtInRect", "ptr", DllStructGetPtr($tRect), "struct*", $tPoint) If IsArray($aRet) Then Return $aRet[0] Return False EndFunc Func GetWindowRect($hWnd, ByRef $tRect) DllCall("user32.dll", "bool", "GetWindowRect", "hwnd", $hWnd, "struct*", $tRect) EndFunc Func GetCursorPos(ByRef $tPoint) DllCall("user32.dll", "bool", "GetCursorPos", "struct*", $tPoint) EndFunc Func SetCapture($hWnd) DllCall("user32.dll", "hwnd", "SetCapture", "hwnd", $hWnd) EndFunc Func ReleaseCapture() DllCall("user32.dll", "bool", "ReleaseCapture") EndFunc Func SetTextColor($hDC, $iColor) DllCall("gdi32.dll", "INT", "SetTextColor", "handle", $hDC, "INT", $iColor) EndFunc Func BeginPaint($hWnd, ByRef $tPAINTSTRUCT) $tPAINTSTRUCT = DllStructCreate($tagPAINTSTRUCT) Local $aRet = DllCall('user32.dll', 'handle', 'BeginPaint', 'hwnd', $hWnd, 'struct*', $tPAINTSTRUCT) If @error Then Return SetError(@error, @extended, 0) Return $aRet[0] EndFunc Func GetTextExtentPoint32($hDC, $sText, $iTextLen, ByRef $tSize) DllCall("gdi32.dll", "bool", "GetTextExtentPoint32W", "handle", $hDC, "wstr", $sText, "int", $iTextLen, "struct*", $tSize) EndFunc Func GradientFill($hDC, $tVertex, $nVertex, $tMesh, $nMesh, $ulMode) DllCall("Msimg32.dll", "BOOL", "GradientFill", _ "handle", $hDC, _ "struct*", $tVertex, _ "ulong", $nVertex, _ "struct*", $tMesh, _ "ulong", $nMesh, _ "ulong", $ulMode) EndFunc Func GetParent($hWnd) Local $aResult = DllCall("user32.dll", "hwnd", "GetParent", "hwnd", $hWnd) If @error Then Return SetError(@error, @extended, 0) Return $aResult[0] EndFunc Func SetBkMode($hDC, $iBkMode) Local $aResult = DllCall("gdi32.dll", "int", "SetBkMode", "handle", $hDC, "int", $iBkMode) If @error Then Return SetError(@error, @extended, 0) Return $aResult[0] EndFunc Func EndPaint($hWnd, ByRef $tPAINTSTRUCT) Local $aRet = DllCall('user32.dll', 'bool', 'EndPaint', 'hwnd', $hWnd, 'struct*', $tPAINTSTRUCT) If @error Then Return SetError(@error, @extended, False) Return $aRet[0] EndFunc Func GetClientRect($hWnd, ByRef $tRect) Local $aRet = DllCall("user32.dll", "bool", "GetClientRect", "hwnd", $hWnd, "struct*", $tRect) If @error Or Not $aRet[0] Then Return SetError(@error + 10, @extended, 0) Return $tRect EndFunc Func TextOut($hDC, $iX, $iY, $sText, $iTextLen = Default) If $iTextLen = Default Then $iTextLen = StringLen($sText) DllCall('gdi32.dll', 'bool', 'TextOutW', 'handle', $hDC, 'int', $iX, 'int', $iY, 'wstr', $sText, 'int', $iTextLen) EndFunc  
    • r0ash
      By r0ash
      Hey guys, MattDiesel over Stackoverflow mentioned this beautiful piece of code 
      #include <WindowsConstants.au3> #include <WinAPI.au3> Local $IDM_FONT = 33 Local $hWindow = WinGetHandle("Untitled - Notepad") _WinAPI_PostMessage($hWindow, $WM_COMMAND, $IDM_FONT, 0) Local $hFontWin = WinWait("Font") $select = ControlCommand($hFontWin, "", "ComboBox1", "GetCurrentSelection", "") WinClose($hFontWin) MsgBox(0,"", $select) I realized that _WinAPI_PostMessage can trigger menu click event, even if Notepad is minimized.
      How do we know what is the decimal value of *any menu item or sub-menu item*? How we know "Format > Font" menu-item is 33 as wParam to _WinAPI_PostMessage()? Have a look at snapshot.
      Regards.

    • Xandy
      By Xandy
      I wanted to start using SDL2 libraries in C++.
      This is a Hello World project that covers some of the essentials of programming with SDL2.
      I will use it when I forget how to create an SDL2 project.
      Loads a scrolling background image for world. Mouse position, left click, and double click example. Hotkeys and cooldown timers to prevent hotkey spam. Plays background music. (ALT + P) Plays sound effects changing sprite type. (numpad: /, *, -, +) Features a Player class for multiplayer. Player collision detection. Uses a Window class from Lazyfoo for maximize button, fullscreen ext.. Built using MSVS 2013 (free).  All dlls and libraries included and linked (for MSVS) using relative paths. You can probably run the SDL2_HelloWorld.sln without setting up any libraries. Note SDL_Net is setup but not used. Delta time used to create consistent frame rate across machines. Player animation sprite sheet:  
      Demo: Slimy's First Kiss
      Download Source and project: http://songersoft.com/programming/sdl2_helloworld/sdl2_helloworld_about.phtml
      This isn't meant to be amazing.  It's just to help get started with SDL2.
      I will consider any criticism.
      main.cpp
      // This example HelloWorld followed this video: // https://www.youtube.com/watch?v=M4Jgz0wEQxY // Turned into this // https://www.youtube.com/watch?v=yRpen8jOa08&list=PL77-op_SRaiEuC0YC43ZAUJJwL_G_C2z8&index=15 // Window class was copied from Lazyfoo // http://lazyfoo.net/tutorials/SDL/35_window_events/index.php #include <iostream> #include <string> #include "SDL.h" #include "SDL_image.h" #include "SDL_ttf.h" #include "SDL_mixer.h" #include "SDL_net.h" #include "Player.h" #include "Window.h" using namespace std; // Prototypes SDL_Texture *LoadTexture(string filepath, SDL_Renderer *renderTarget); void logSDLError(const string); SDL_Rect sdlrect(int, int, int, int); SDL_Surface *OptimizedSurface(string filepath, SDL_Surface *windowSurface); // if(okAlt) either Alt key is pressed OrKeyALT #define okAlt (k[SDL_SCANCODE_RALT] || k[SDL_SCANCODE_LALT]) int main(int argc, char *argv[]) { // Needed for the initialize block Window window; SDL_Renderer *renderTarget = nullptr; // Initialize SDL2 if (SDL_Init(SDL_INIT_EVERYTHING) < 0) { logSDLError("SDL_Init "); } // Initialize SDL_image if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) { cout << "Could not initialize SDL_image: " << IMG_GetError() << std::endl; SDL_Delay(5500); } // Initialize TTF if (TTF_Init() < 0) cout << "TTF_Init " << TTF_GetError() << endl; //Create window if (!window.init("SDL2 Hello World", 640, 480, "../../Graphics/iconbmp.bmp")) { printf("Window could not be created! SDL Error: %s\n", SDL_GetError()); } else { //Create renderer for window renderTarget = window.createRenderer(); if (renderTarget == NULL) { printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); } } // Audio if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) { cout << "Mix_OpenAudio: " << Mix_GetError() << endl; } // Load sounds: Run chunk if less than 10 sec, music if greater (generally) //Mix_Music *bgm = Mix_LoadMUS("../../Sounds/overworld.mid"); // Can't Pause MIDI Mix_Music *bgm = Mix_LoadMUS("../../Sounds/bensound-goinghigher.mp3"); cout << Mix_GetError() << endl; // Font and text SDL_Texture *text_texture = nullptr; SDL_Color textColor = { 144, 77, 255, 255 }; TTF_Font *font = TTF_OpenFont("../../Graphics/Fonts/VCR_OSD_MONO.ttf", 20); if (font) { SDL_Surface *textSurf = TTF_RenderText_Solid(font, "Hello world", textColor); text_texture = SDL_CreateTextureFromSurface(renderTarget, textSurf); SDL_FreeSurface(textSurf); } else cout << TTF_GetError() << endl; SDL_Rect textRect = { 0, 0, 0, 0 };// Position of text on window // Get the size of the text_texture SDL_QueryTexture(text_texture, NULL, NULL, &textRect.w, &textRect.h); const int playerMax = 8; int players = 2; float prevTime = 0, currentTime = 0, deltaTime = 0; bool fullscreen_toggle = 0; int i = 0, ii = 0; int redraw = 1; bool done = 0; // Load player sprite sheet and background texture SDL_Texture *spritesheet_texture = LoadTexture("../../Graphics/DW3_Char_SpriteSheet.png", renderTarget); SDL_Texture *bg_texture = LoadTexture("../../Graphics/dw3-over.png", renderTarget); int bg_texture_w = 0, bg_texture_h = 0; // Point k to Keyboard state (only needs done here, not in main loop) const Uint8 *k = SDL_GetKeyboardState(NULL); SDL_Event windowEvent; // Stop keys spamming (like music ON / OFF) float key_cooldown_timer_max = 500.0f, key_cooldown_timer = 0; SDL_Rect cameraRect = { 0, 0, window.getWidth(), window.getHeight()}; // Construct default players Player player[playerMax]; // Customize players (texture and position) for (i = 0; i < players; i++)//(sprite texture, position x, position y) player[i].Player_new(spritesheet_texture, window.getWidth() / 2 + i * 16, window.getHeight() / 2); // Get the size of bg_texture SDL_QueryTexture(bg_texture, NULL, NULL, &bg_texture_w, &bg_texture_h); // Main message loop while (!done) { prevTime = currentTime; currentTime = SDL_GetTicks(); deltaTime = (currentTime - prevTime) / 1000.0f; while (SDL_PollEvent(&windowEvent) != 0) { // Check for events if (windowEvent.type == SDL_QUIT) { // Window Exit done = 1; } else if(windowEvent.type == SDL_MOUSEBUTTONDOWN) { // Mouse buttons if (windowEvent.button.clicks == 2) { // Double left click redraw = 1; } else if (windowEvent.button.button == SDL_BUTTON_LEFT) { // Single left click redraw = 1; } // Output mouse position cout << "Mouse: " << windowEvent.button.x << " " << windowEvent.button.y << endl; } }// if(SDL_PollEvent(&windowEvent)) if (okAlt) { // Either ALT key if (k[SDL_SCANCODE_RETURN]) { // ALT + ENTER, toggle fullscreen // Consider matching current window resolution to closest preset array of valid full screen resolutions. fullscreen_toggle = 1; } if (k[SDL_SCANCODE_P]) { if (SDL_GetTicks() - key_cooldown_timer > key_cooldown_timer_max) { // Action cooldown timer is ready. Avoids ON / OFF flicker // Play Music if (!Mix_PlayingMusic()) { cout << "PLAY"; Mix_PlayMusic(bgm, -1); } else if (Mix_PausedMusic()) { cout << "RESUME"; Mix_ResumeMusic(); } else { cout << "PAUSE"; Mix_PauseMusic(); } key_cooldown_timer = SDL_GetTicks(); } }// SDL_SCANCODE_P if (k[SDL_SCANCODE_S]) { // Stop Music Mix_HaltMusic(); } }// okAlt //Handle window events fullscreen_toggle = window.handleEvent(windowEvent, renderTarget, fullscreen_toggle); // Player Update and IntersectsWith for (i = 0; i < players; i++) { player[i].Update(deltaTime, k); for (ii = 0; ii < players; ii++) { if(i != ii)// Not self player[i].IntersectsWith(player[ii]); } } // Camera cameraRect.x = player[0].GetOriginX() - window.getWidth() / 2; cameraRect.y = player[0].GetOriginY() - window.getHeight() / 2; // Normalize if (cameraRect.x < 0) cameraRect.x = 0; if (cameraRect.y < 0) cameraRect.y = 0; if (cameraRect.x + cameraRect.w >= bg_texture_w) cameraRect.x = bg_texture_w - window.getWidth(); if (cameraRect.y + cameraRect.h >= bg_texture_h) cameraRect.y = bg_texture_h - window.getHeight(); redraw = 1; // Don't judge me if (redraw) { // Redraw should definatly pretty much be at the end of loop // Clear window SDL_RenderClear(renderTarget); // Copy camera from bg_texture SDL_RenderCopy(renderTarget, bg_texture, &cameraRect, NULL); // Draw players for (i = 0; i < players; i++) player[i].Draw(renderTarget, cameraRect); // Print text SDL_RenderCopy(renderTarget, text_texture, NULL, &textRect); // Show the rendered content SDL_RenderPresent(renderTarget); redraw = 0; }// if(redraw) }// while(true) // Free windows window.free(); SDL_DestroyTexture(bg_texture); SDL_DestroyTexture(spritesheet_texture); SDL_DestroyTexture(text_texture); TTF_CloseFont(font); // Free Renderers SDL_DestroyRenderer(renderTarget); // Free music Mix_FreeMusic(bgm); // Close systems Mix_Quit(); TTF_Quit(); IMG_Quit(); SDL_Quit(); return EXIT_SUCCESS; }// main() SDL_Texture *LoadTexture(string filepath, SDL_Renderer *renderTarget) { // Create texture SDL_Texture *texture = nullptr; // Load surface SDL_Surface *surface = IMG_Load(filepath.c_str()); if (surface == NULL) { // surface didn't load logSDLError("LoadTexture surface "); } else { SDL_SetColorKey(surface, SDL_TRUE, SDL_MapRGB(surface->format, 0, 0, 0)); texture = SDL_CreateTextureFromSurface(renderTarget, surface); //SDL_SetTextureColorMod(texture, 120, 150, 140); if (texture == NULL) logSDLError("LoadTexture texture "); } SDL_FreeSurface(surface); return texture; } void logSDLError(const string msg){ cout << msg << " Error: " << SDL_GetError() << endl; SDL_Delay(4000); } SDL_Rect sdlrect(int x, int y, int w, int h) { SDL_Rect rect = {x, y, w, h}; return rect; } SDL_Surface *OptimizedSurface(string filepath, SDL_Surface *windowSurface) { SDL_Surface *optimizedSurf = nullptr; SDL_Surface *surface = IMG_Load(filepath.c_str()); if (surface == NULL) { cout << "Error: " << endl; } else { optimizedSurf = SDL_ConvertSurface(surface, windowSurface->format, 0); if (optimizedSurf == NULL) cout << "Error: " << endl; } SDL_FreeSurface(surface); return optimizedSurf; } Player.h
      #pragma once #include <iostream> #include "SDL.h" #include <String> #include "SDL_mixer.h" using namespace std; enum player_control { ePlayer_control_up, ePlayer_control_down, ePlayer_control_left, ePlayer_control_right, ePlayer_control_type_minus, ePlayer_control_type_plus }; class Player { private: SDL_Rect cropRect; SDL_Texture *texture; int spritesheet_texture_w, spritesheet_texture_h;//size of spritesheet texture bool isActive;//animation timer SDL_Scancode keys[6]; int frame_w, frame_h;//16, 16 float frameTimerMax; float frameTimer;//0..frameTimerMax int frame;//0..1 int frameMax;//2 int way;//0..3 int classType;//0..53 float moveSpeed; float cast_cooldown_max; Mix_Chunk *soundEffect; int originX, originY; int radius; Uint32 key_cooldown_timer; string name; public: void Player_new(SDL_Texture *spritesheet_texture, int x, int y); Player(); ~Player(); void Update(float delta, const Uint8 *keyState); void Draw(SDL_Renderer *renderTarget, SDL_Rect cameraRect); bool IntersectsWith(Player &p); int GetOriginX(); int GetOriginY(); int GetRadius(); SDL_Rect positionRect; }; Player.cpp
      #pragma once #include "Player.h" #include "SDL_image.h" #include "SDL_mixer.h" #include <iostream> #include <String> #include <cmath> using namespace std; Player::Player() { cropRect = {0, 0, 16, 16}; texture = nullptr; spritesheet_texture_w = spritesheet_texture_h = 0;//size of spritesheet texture isActive = false;//animation timer keys[6]; frame_w = frame_h = 16;//16, 16 frameTimerMax = 0.5f; frameTimer = 0;//0..frameTimerMax frame = 0;//0..1 frameMax = 2;//2 way = 0;//0..3 classType = 0;//0..53 moveSpeed = 200.0f; radius = frame_w / 2; soundEffect = nullptr; key_cooldown_timer = 0; cast_cooldown_max = 190.0f; static int playerNumber = 0; playerNumber++; name = "Player:" + to_string(playerNumber); // Setup keys for player 1 // ** I see the enum didn't exist when this was written ** if (playerNumber == 1) { keys[0] = SDL_SCANCODE_W; keys[1] = SDL_SCANCODE_S; keys[2] = SDL_SCANCODE_A; keys[3] = SDL_SCANCODE_D; keys[4] = SDL_SCANCODE_KP_MINUS; keys[5] = SDL_SCANCODE_KP_PLUS; } else { // Setup keys all other players (not 1) keys[0] = SDL_SCANCODE_UP; keys[1] = SDL_SCANCODE_DOWN; keys[2] = SDL_SCANCODE_LEFT; keys[3] = SDL_SCANCODE_RIGHT; keys[4] = SDL_SCANCODE_KP_DIVIDE; keys[5] = SDL_SCANCODE_KP_MULTIPLY; } }//Player::Player() void Player::Player_new(SDL_Texture *spritesheet_texture, int x, int y) { // This is new player isActive = false; // Read size of spritesheet texture SDL_QueryTexture(spritesheet_texture, NULL, NULL, &spritesheet_texture_w, &spritesheet_texture_h); texture = spritesheet_texture; // spritesheet rect cropRect = { 0, 0, 16, 16 }; // player screen position positionRect = { x, y, 16, 16 }; // Defaults moveSpeed = 200.0f; radius = frame_w / 2; frameTimer = 0; frame = 0; frameMax = 2; way = 0; classType = 0; originX = frame_w / 2; originY = frame_h / 2; soundEffect = Mix_LoadWAV("../../Sounds/whipcrack1.wav"); cout << "Name: " << name << endl; }//Player::Player_new() void Player::Update(float delta, const Uint8 *keyState) { isActive = true; if (keyState[keys[ePlayer_control_up]]) { way = 0; positionRect.y -= moveSpeed * delta; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); } if (keyState[keys[ePlayer_control_down]]) { way = 1; positionRect.y += moveSpeed * delta; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); } if (keyState[keys[ePlayer_control_left]]) { way = 3; positionRect.x -= moveSpeed * delta; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); } if (keyState[keys[ePlayer_control_right]]) { way = 2; positionRect.x += moveSpeed * delta; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); } if (keyState[keys[ePlayer_control_type_minus]]) { if (SDL_GetTicks() - key_cooldown_timer > cast_cooldown_max) { key_cooldown_timer = SDL_GetTicks(); Mix_PlayChannel(-1, soundEffect, 0); classType--; if (classType < 0) classType = spritesheet_texture_h / cropRect.h - 1; cropRect.y = classType * cropRect.h; } } if (keyState[keys[ePlayer_control_type_plus]]) { if (SDL_GetTicks() - key_cooldown_timer > cast_cooldown_max) { key_cooldown_timer = SDL_GetTicks(); Mix_PlayChannel(-1, soundEffect, 0); classType++; if (classType >= spritesheet_texture_h / cropRect.h) classType = 0; cropRect.y = classType * cropRect.h; } } if (isActive) { frameTimer += delta; if (frameTimer >= frameTimerMax){ frameTimer = 0; cropRect.x = (way * cropRect.w * frameMax) + (frame * cropRect.w); if (frame >= frameMax - 1) frame = 0; else frame++; } } else { frameTimer = 0; } }//Player::Update() void Player::Draw(SDL_Renderer *renderTarget, SDL_Rect cameraRect) { SDL_Rect drawingRect = { positionRect.x - cameraRect.x, positionRect.y - cameraRect.y, positionRect.w, positionRect.h }; SDL_RenderCopy(renderTarget, texture, &cropRect, &drawingRect); } bool Player::IntersectsWith(Player &p){ if (sqrt(pow(GetOriginX() - p.GetOriginX(), 2) + pow(GetOriginY() - p.GetOriginY(), 2)) >= radius + p.GetRadius()) { SDL_SetTextureColorMod(texture, 255, 255, 255); return false; } SDL_SetTextureColorMod(texture, 255, 0, 0); return true; } Player::~Player() { SDL_DestroyTexture(texture); Mix_FreeChunk(soundEffect); } int Player::GetOriginX() { return positionRect.x + originX; } int Player::GetOriginY() { return positionRect.y + originY; } int Player::GetRadius() { return radius; }  
    • chacoya121
      By chacoya121
      plz help explain between GDI+ and Winapi, is it desktop inside another desktop, 3 layer dimension?
      i can't get the picture
      1. u get desktop u can visual see
      2. then u create GDI+ startup another desktop screen dimension?
      3. then u have Winapi command inside GDI+, is this another desktop screen dimension? cuz GDI+ could create bitmap that is one dimension? Winapi get windowDC also another dimension?
      plz help and explain, with picture would be nice, im not good with visualize ("dumb newbie"), still learning
      newbie to programming world
      thankyou.
    • IErrors
      By IErrors
      I am working on some functionality to detect whether a standard keyboard was used for input in my UI or if a barcode scanner (that acts like a keyboard) was used. Instead of dealing with a scanner SDK, I decided I would read from the raw input to get device info and make a determination.
      I discovered while testing with multiple UIs is that when the WM_INPUT message is received and the function called, the $hWnd param is always the same (apparently whatever handle I set the "hTarget" to in the RAWINPUTDEVICE struct).
      Is this normal behavior??
      Using the test code below, no matter what window you give input to the $hWnd param never changes.
      #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <WinAPISys.au3> $Form1 = GUICreate("Form 1", 300, 300, -1, 10) ConsoleWrite("$Form1 = " & $Form1 & @CRLF) $Edit1 = GUICtrlCreateEdit("", 0, 0, 300, 300) GUISetState(@SW_SHOW, $Form1) $Form2 = GUICreate("Form 2", 300, 300, -1, 350) ConsoleWrite("$Form2 = " & $Form2 & @CRLF) $Edit2 = GUICtrlCreateEdit("", 0, 0, 300, 300) GUISetState(@SW_SHOW, $Form2) GUIRegisterMsg($WM_INPUT, "WM_INPUT") ; https://msdn.microsoft.com/en-us/library/ms645590(v=vs.85).aspx $tRID = DllStructCreate($tagRAWINPUTDEVICE) ; https://msdn.microsoft.com/en-us/library/ms645565(v=vs.85).aspx DllStructSetData($tRID, "UsagePage", 1) DllStructSetData($tRID, "Usage", 6) DllStructSetData($tRID, "Flags", 0) DllStructSetData($tRID, "hTarget", $Form1) ; According to the struct def, if hTarget=NULL then it should follow keyboard focus. - nope :( $pRID = DllStructGetPtr($tRID) _WinAPI_RegisterRawInputDevices($pRID) ; https://msdn.microsoft.com/en-us/library/ms645600(v=vs.85).aspx Do Until GUIGetMsg() = $GUI_EVENT_CLOSE Func WM_INPUT($hWnd, $iMsg, $wParam, $lParam) ConsoleWrite("hWnd = " & $hWnd & " | Title = " & WinGetTitle($hWnd) & @CRLF) ConsoleWrite("Active Window = " & WinGetTitle("[ACTIVE]") & @CRLF) Return $GUI_RUNDEFMSG EndFunc ;==>WM_INPUT