In the function waveOutOpen, you need to pass a WAVEFORMATEX, yet if you do Len and LenB on WAVEFORMATEX, you'll notice that LenB is bigger than Len, indicating that the in-memory copy of a WAVEFORMATEX UDT in VB6 is in fact padded (due to the mixture of Integer and Long data types). Giving a padded copy of the structure to an API function will make it crash. Do you have any idea what the best way to go about this is? WAVEFORMATEX is most certainly required for the use of waveOutOpen.
↧
How do I pass WAVEFORMATEX to API functions?
↧
Click button on a toolbar in another program
Hi,
I have searched the internet looking for how to click a button on a toolbar in another program (not internet Explorer). I found couple, but they are beyond the my capability of understanding. I am stuck at the below part ( I used spy++ to help me to get the windows handles). When I sendmessage I don't know what to put in wparam argument.
.
.
I appreciate your help.
I have searched the internet looking for how to click a button on a toolbar in another program (not internet Explorer). I found couple, but they are beyond the my capability of understanding. I am stuck at the below part ( I used spy++ to help me to get the windows handles). When I sendmessage I don't know what to put in wparam argument.
.
.
Code:
ChildRet4 = FindWindowEx(ChildRet3, ByVal 0&, "msvb_lib_toolbar", vbNullString)
SendMessage(ChildRet4, WM_COMMAND, ???, ByVal 0)
I appreciate your help.
↧
↧
What's wrong with my usage of WriteConsoleOutputCharacter?
Here's my code.
What it should do is display the text "This is a test." in the console window, when you click the button Command1. But it's not working. By printing out the variable CharCount (the return value for number of characters written to the console), you can see that it indeed THINKS that it put that text into the console, but if you look at the console you'll see NO TEXT. And if you look at the printed value after CharCount, which is ErrNum (the error number returned from Err.LastDllError, which is the same as the API call GetLastError) it shows 87 (or 0x57 in hexadecimal). I don't know what error 87 means.
Code:
Private Declare Function AllocConsole Lib "kernel32.dll" () As Long
Private Declare Function FreeConsole Lib "kernel32.dll" () As Long
Private Declare Function GetStdHandle Lib "kernel32.dll" (ByVal nStdHandle As Long) As Long
Private Declare Function WriteConsoleOutputCharacter Lib "kernel32.dll" Alias "WriteConsoleOutputCharacterA" (ByVal hConsoleOutput As Long, ByVal lpCharacter As String, ByVal nLength As Long, ByRef dwWriteCoord As COORD, ByRef lpNumberOfCharsWritten As Long) As Long
Private Const STD_OUTPUT_HANDLE As Long = -11&
Private Type COORD
x As Integer
y As Integer
End Type
Dim hStdOut As Long
Private Sub Form_Load()
AllocConsole
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE)
End Sub
Private Sub Form_Unload(Cancel As Integer)
FreeConsole
End Sub
Private Sub Command1_Click()
Dim Text As String
Dim Pos As COORD
Dim CharCount As Long
Dim ErrNum As Long
Text = "This is a test."
With Pos
.x = 0
.y = 0
End With
WriteConsoleOutputCharacter hStdOut, Text, Len(Text), Pos, CharCount
ErrNum = Err.LastDllError
Print CharCount
Print ErrNum
End Sub
What it should do is display the text "This is a test." in the console window, when you click the button Command1. But it's not working. By printing out the variable CharCount (the return value for number of characters written to the console), you can see that it indeed THINKS that it put that text into the console, but if you look at the console you'll see NO TEXT. And if you look at the printed value after CharCount, which is ErrNum (the error number returned from Err.LastDllError, which is the same as the API call GetLastError) it shows 87 (or 0x57 in hexadecimal). I don't know what error 87 means.
↧
SafeArrayLock versus SafeArrayAccessData?
Based on the MSDN descriptions of these, it sounds like they both give you a pointer you can use to access the data stored in a SafeArray. So what exactly is the difference?
↧
Is it possible to do a non-blocking console read?
I would like to be able to read any and all characters that are currently in the console buffer, without knowing how many are in the buffer. If there's one character in the buffer, it should read that one character and return. If there's 100 characters in the buffer, it should read those 100 characters and return. If NO characters are in the buffer it should return immediately without reading anything. It should NEVER stop running (engage in a blocking operation) while waiting for something to read. Is it possible to do this with the console API functions?
↧
↧
Is it possible to put AddressOf in a variable
I would like to create a Sub that can transfer an address of a subroutine, I've tried Long and Long_Ptr without success.
Function WndProc_Sounds
'working stuff is in here
End Function
Function SubClass_iDrive(hWnd as Long, lProc as Long, WndProc as Long) as Long
'of course the following line works if I use it outside the Function and insert the real variables
If lProc = False Then lProc = SetWindowLong (hWnd, GWL_WNDPROC, AddressOf WndProc)
End Function
My call:
Dim lProcSounds as Long
Dim hWndSounds as Long
hWndSounds = iDriveSound.hWnd
SubClass_iDrive hWndSounds, lProcSounds, AddressOf WndProc_Sounds
How can this be accomplished???
Function WndProc_Sounds
'working stuff is in here
End Function
Function SubClass_iDrive(hWnd as Long, lProc as Long, WndProc as Long) as Long
'of course the following line works if I use it outside the Function and insert the real variables
If lProc = False Then lProc = SetWindowLong (hWnd, GWL_WNDPROC, AddressOf WndProc)
End Function
My call:
Dim lProcSounds as Long
Dim hWndSounds as Long
hWndSounds = iDriveSound.hWnd
SubClass_iDrive hWndSounds, lProcSounds, AddressOf WndProc_Sounds
How can this be accomplished???
↧
There's a bug in ReadConsole
Not sure if this is unique to VB6 or for all uses of ReadConsole. However, here's what I've discovered. In my test, you have a command button that calls ReadConsole. There are 3 ways of using it, but one has a bug.
In the first way, you click the command button, and then type some text into the console. As you type it, it appears. Then press Enter to complete the action, and the ReadConsole will place what you typed in the readout buffer.
In the second way, you type what you want and then hit the Enter key in the console, before clicking the command button. The text will be invisible until you click the command button. The moment you click it, the text will appear in the console, and be sent to the readout buffer.
In the third way, you type what you want in the console, but don't hit the Enter key yet. Now click the command button. You now will see the text appear in the console, and also anything else you type will be immediately displayed in the console. So at this point, hit the Enter key. The readout buffer will now hold the text you typed, but there's a glitch. The first character will NOT be what you typed. Instead, it will be replaced with either a "P" or a "V". One is if you use the program while in the VB6 IDE. The other is if you use the program from a compiled EXE file (assuming it is compiled in Native code mode, not P-code mode).
Something funny is going on with the bytes stored in memory, but I'm not sure what. Is this a well known bug?
In the first way, you click the command button, and then type some text into the console. As you type it, it appears. Then press Enter to complete the action, and the ReadConsole will place what you typed in the readout buffer.
In the second way, you type what you want and then hit the Enter key in the console, before clicking the command button. The text will be invisible until you click the command button. The moment you click it, the text will appear in the console, and be sent to the readout buffer.
In the third way, you type what you want in the console, but don't hit the Enter key yet. Now click the command button. You now will see the text appear in the console, and also anything else you type will be immediately displayed in the console. So at this point, hit the Enter key. The readout buffer will now hold the text you typed, but there's a glitch. The first character will NOT be what you typed. Instead, it will be replaced with either a "P" or a "V". One is if you use the program while in the VB6 IDE. The other is if you use the program from a compiled EXE file (assuming it is compiled in Native code mode, not P-code mode).
Something funny is going on with the bytes stored in memory, but I'm not sure what. Is this a well known bug?
↧
Buffers & security question
So it's been a loooooong time since I've properly done any Win32 API stuff. Years ago, samples like these (& my code too) were commonplace: http://allapi.mentalis.org/apilist/EnumPrinters.shtml# or http://word.mvps.org/faqs/macrosvba/...lePrinters.htm.
In essence:
[LIST][1]Try an API call once, passing a dummy value for one of the byref buffer-length related parameters
[2]Check the return value - if it didn't work, use the retrieved buffer length (now known) & just call the same API call again[/ LIST]
Um, so wouldn't this cause one of those nasty buffer overflow security leak errors I've heard so much about in the news, causing potentially full remote control? What's the 2016 preferred way of coding & calling APIs with buffer length parameters please?
In essence:
[LIST][1]Try an API call once, passing a dummy value for one of the byref buffer-length related parameters
[2]Check the return value - if it didn't work, use the retrieved buffer length (now known) & just call the same API call again[/ LIST]
Um, so wouldn't this cause one of those nasty buffer overflow security leak errors I've heard so much about in the news, causing potentially full remote control? What's the 2016 preferred way of coding & calling APIs with buffer length parameters please?
↧
[RESOLVED] Is it possible to put AddressOf in a variable
I would like to create a Sub that can transfer an address of a subroutine, I've tried Long and Long_Ptr without success.
Function WndProc_Sounds
'working stuff is in here
End Function
Function SubClass_iDrive(hWnd as Long, lProc as Long, WndProc as Long) as Long
'of course the following line works if I use it outside the Function and insert the real variables
If lProc = False Then lProc = SetWindowLong (hWnd, GWL_WNDPROC, AddressOf WndProc)
End Function
My call:
Dim lProcSounds as Long
Dim hWndSounds as Long
hWndSounds = iDriveSound.hWnd
SubClass_iDrive hWndSounds, lProcSounds, AddressOf WndProc_Sounds
How can this be accomplished???
Function WndProc_Sounds
'working stuff is in here
End Function
Function SubClass_iDrive(hWnd as Long, lProc as Long, WndProc as Long) as Long
'of course the following line works if I use it outside the Function and insert the real variables
If lProc = False Then lProc = SetWindowLong (hWnd, GWL_WNDPROC, AddressOf WndProc)
End Function
My call:
Dim lProcSounds as Long
Dim hWndSounds as Long
hWndSounds = iDriveSound.hWnd
SubClass_iDrive hWndSounds, lProcSounds, AddressOf WndProc_Sounds
How can this be accomplished???
↧
↧
Question about Sleep API
Does the Sleep API function make only the current thread "sleep" (in a mulitithreaded application) or does it cause the entire process (all the threads) to sleep?
↧
TibiaAPI.dll for Tibia 8.60
Hello, guys!
Someone has the TibiaAPI for 8.60?
I searched the internet and found nothing. The websites https://code.google.com/archive/p/tibiaapi/downloads and http://tibiaapi.googlecode.com/files...6_08-18-10.zip does not work.
Wx99,
Thanks.
Someone has the TibiaAPI for 8.60?
I searched the internet and found nothing. The websites https://code.google.com/archive/p/tibiaapi/downloads and http://tibiaapi.googlecode.com/files...6_08-18-10.zip does not work.
Wx99,
Thanks.
↧
Is there any kind of third party library for making API calls
I am looking for some kind of third-party library or wrapper (free or purchase) that I can use to make it easier to write code for calling Win API functions, with VB keywords or some such, rather than the limited functions available via .Net classes (although a class lib would be great if it was much more comprehensive than the .Net classes available just for common tasks like messages etc.).
What I want is something similar to what you get in PowerBasic or PureBasic, where you can just use a sort of keyword with parameters to call a Win API function, rather than directly looking up and using the API functions that Windows offers, which are very complex.
Any suggestions (other than spending a lot of time writing my own class :=) )?
Thanks
Pete B
What I want is something similar to what you get in PowerBasic or PureBasic, where you can just use a sort of keyword with parameters to call a Win API function, rather than directly looking up and using the API functions that Windows offers, which are very complex.
Any suggestions (other than spending a lot of time writing my own class :=) )?
Thanks
Pete B
↧
PostMessage Button Click without mouse pointer (VB.Net)
Hello,
I'm trying to develop some code to do a button click onto an application without moving the cursor over to it. The code below is just not doing clicking actions or an error. Its setting focus but not doing a click, and I've tried several different X/Y combinations. Not sure what is going on. Ultimately I'd like to be able to click things on a window even if its not focused... I've searched online for days and I find the similar code repeating but I don't understand how I'm not getting it to work! Any help appreciated thanks!
Edit :: I can't see any messages under Spy++ so, this might not be a Win32 application? wpf perhaps? Does anyone have experience with clicking on these applications?
Public Class Main
Public Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONUP = &H202
Private Const BM_CLICK = &HF5
Private Const WM_ACTIVATE = &H6
Private Const MA_ACTIVATE = 1
Private Const MK_LBUTTON = &H1
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As IntPtr
Private Declare Function SetFocus Lib "user32.dll" (ByVal hwnd As Int32) As Int32
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32
Private Sub cmdBSPerform_Click(sender As Object, e As EventArgs) Handles cmdBSPerform.Click
Dim lParam As Int32
Dim hwnd As Long = FindWindow(vbNullString, "BlueStacks App Player")
Select Case cmbBSPerforms.SelectedItem
Case "LeftClick"
lParam = MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text)
SetForegroundWindow(hwnd)
SetFocus(hwnd)
PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text))
PostMessage(hwnd, WM_LBUTTONUP, 0, MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text))
PostMessage(hwnd, WM_LBUTTONDOWN, 1, MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text))
PostMessage(hwnd, WM_LBUTTONUP, 0, MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text))
End Select
End Sub
Public Function MakeLParam(ByVal LoWord As Int32, ByVal HiWord As Int32) As Int32
Return (HiWord << 16) Or (LoWord And &HFFFF)
End Function
End Class
I'm trying to develop some code to do a button click onto an application without moving the cursor over to it. The code below is just not doing clicking actions or an error. Its setting focus but not doing a click, and I've tried several different X/Y combinations. Not sure what is going on. Ultimately I'd like to be able to click things on a window even if its not focused... I've searched online for days and I find the similar code repeating but I don't understand how I'm not getting it to work! Any help appreciated thanks!
Edit :: I can't see any messages under Spy++ so, this might not be a Win32 application? wpf perhaps? Does anyone have experience with clicking on these applications?
Public Class Main
Public Const WM_LBUTTONDOWN = &H201
Public Const WM_LBUTTONUP = &H202
Private Const BM_CLICK = &HF5
Private Const WM_ACTIVATE = &H6
Private Const MA_ACTIVATE = 1
Private Const MK_LBUTTON = &H1
Public Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32
Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As IntPtr
Private Declare Function SetFocus Lib "user32.dll" (ByVal hwnd As Int32) As Int32
Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32
Private Sub cmdBSPerform_Click(sender As Object, e As EventArgs) Handles cmdBSPerform.Click
Dim lParam As Int32
Dim hwnd As Long = FindWindow(vbNullString, "BlueStacks App Player")
Select Case cmbBSPerforms.SelectedItem
Case "LeftClick"
lParam = MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text)
SetForegroundWindow(hwnd)
SetFocus(hwnd)
PostMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text))
PostMessage(hwnd, WM_LBUTTONUP, 0, MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text))
PostMessage(hwnd, WM_LBUTTONDOWN, 1, MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text))
PostMessage(hwnd, WM_LBUTTONUP, 0, MakeLParam(txtXBSPerform.Text, txtYBSPerform.Text))
End Select
End Sub
Public Function MakeLParam(ByVal LoWord As Int32, ByVal HiWord As Int32) As Int32
Return (HiWord << 16) Or (LoWord And &HFFFF)
End Function
End Class
↧
↧
copymemory code not working with framework 4.5.1
I made a wrapper class for Ghostscript that works with framework 3.5, but not with framework 4.5.1.
I am using VB.NET 2013.
The Initialization code is:
If fails when it is called with this code.
This is the error I am receiving.
-----
PInvokeStackImbalance occurred
Message: Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Users\TGroff.PSI\Documents\Visual Studio 2013\Projects\SandBox\TestPdfThumbnails\TestPdfThumbnails\bin\x86\Debug\TestPdfThumbnails.vshost.exe '.
Additional information: A call to PInvoke function 'TestPdfThumbnails!TestPdfThumbnails.clsPDF::CopyMemory' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
-----
What do I do to make this work in framework 4.5.1?
I am using VB.NET 2013.
The Initialization code is:
Code:
' Copyright (c) 2002 Dan Mount and Ghostgum Software Pty Ltd
'
' Permission is hereby granted, free of charge, to any person obtaining
' a copy of this software and associated documentation files (the
' "Software"), to deal in the Software without restriction, including
' without limitation the rights to use, copy, modify, merge, publish,
' distribute, sublicense, and/or sell copies of the Software, and to
' permit persons to whom the Software is furnished to do so, subject to
' the following conditions:
'
' The above copyright notice and this permission notice shall be
' included in all copies or substantial portions of the Software.
'
' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
' EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
' MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
' NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
' BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
' ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
' CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
' SOFTWARE.
Option Strict Off
Option Explicit Off
Imports System.Runtime.InteropServices
Public Class clsPDF
'------------------------------------------------
'UDTs Start
'------------------------------------------------
<StructLayout(LayoutKind.Sequential)> Public Structure GS_Revision
Public strProduct As IntPtr
Public strCopyright As IntPtr
Public intRevision As Integer
Public intRevisionDate As Integer
End Structure
'------------------------------------------------
'UDTs End
'------------------------------------------------
'------------------------------------------------
'API Calls Start
'------------------------------------------------
'Win32 API
'GhostScript API
<DllImportAttribute("kernel32", entrypoint:="RtlMoveMemory")> _
Private Shared Sub CopyMemory(ByVal dest As IntPtr, ByVal source As IntPtr, ByVal bytes As Long)
End Sub
'...
Code:
Public Function gsdll_stdout(ByVal intGSInstanceHandle As IntPtr, ByVal strz As IntPtr, ByVal intBytes As Integer) As Integer
' If you can think of a more efficient method, please tell me!
' We need to convert from a byte buffer to a string
' First we create a byte array of the appropriate size
Dim aByte(intBytes) As Byte
' Then we get the address of the byte array
Dim gcByte As GCHandle = GCHandle.Alloc(aByte, GCHandleType.Pinned)
Dim ptrByte As IntPtr = gcByte.AddrOfPinnedObject()
' Then we copy the buffer to the byte array
CopyMemory(ptrByte, strz, intBytes) ' <=========== HERE
' Release the address locking
ptrByte = IntPtr.Zero
gcByte.Free()
' Then we copy the byte array to a string, character by character
Dim str As String = ""
Dim i As Integer
For i = 0 To intBytes - 1
str = str + Chr(aByte(i))
Next
' Finally we output the message
Console.Write(str)
gsdll_stdout = intBytes
End Function
-----
PInvokeStackImbalance occurred
Message: Managed Debugging Assistant 'PInvokeStackImbalance' has detected a problem in 'C:\Users\TGroff.PSI\Documents\Visual Studio 2013\Projects\SandBox\TestPdfThumbnails\TestPdfThumbnails\bin\x86\Debug\TestPdfThumbnails.vshost.exe '.
Additional information: A call to PInvoke function 'TestPdfThumbnails!TestPdfThumbnails.clsPDF::CopyMemory' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
-----
What do I do to make this work in framework 4.5.1?
↧
[RESOLVED] Faster CopyMemory for 32 bits?
I use the following CopyMemory call to copy 4 bytes.
CopyMemory ByVal VarPtr(Dest), ByVal VarPtr(Src), 4
The variables' addresses are guaranteed to be at 32-bits boundaries (resp., 64 bits).
The CPU certainly is faster to copy 32 bits once than to iterate 4 times through a bytes sequence.
Question: Is there any 32 bits CopyMemory API function such as:
CopyMemoryWord ByVal VarPtr(Dest), ByVal VarPtr(Src)
?
CopyMemory ByVal VarPtr(Dest), ByVal VarPtr(Src), 4
The variables' addresses are guaranteed to be at 32-bits boundaries (resp., 64 bits).
The CPU certainly is faster to copy 32 bits once than to iterate 4 times through a bytes sequence.
Question: Is there any 32 bits CopyMemory API function such as:
CopyMemoryWord ByVal VarPtr(Dest), ByVal VarPtr(Src)
?
↧
FTPPutFile and Progress Bar
I have successfully made a Download routine in an FTP program by placing a routine under INTERNET_STATUS_RESPONSE_RECEIVED flag in a FTPCallbackStatus Function when using FTPGetFile. This grabs the Bytes being downloaded by using the MoveMemory function then sends the Bytes to a Progressbar. However, I cannot get Bytes to show in an Upload routine using FTPPutFile. The only flag I can get moving memory information is from the INTERNET_STATUS_HANDLE_CREATED flag, but it doesn't show "moving" memory; It will show 1 hunk of memory then go to 100%. The Progress bar finishes before the Upload is complete. Any suggestions as to how to extract the "moving/uploaded" Bytes using FTPPutFile or one of the FTP flags?
Thank you in advance for any help.
Thank you in advance for any help.
↧
Make Treeview Using API
What is the code to make and position a Treeview using API? I also want to put specific text into each of the nodes. Thank you.
↧
↧
[RESOLVED] Make Treeview Using API
What is the code to make and position a Treeview using API? I also want to put specific text into each of the nodes. Thank you.
↧
Windows Messages Constants #1
Found this on another website and thought it would be helpful for WindowsMessages Constants:
Code:
WM_NULL = &H0
WM_CREATE = &H1
WM_DESTROY = &H2
WM_MOVE = &H3
WM_SIZE = &H5
WM_ACTIVATE = &H6
WM_SETFOCUS = &H7
WM_KILLFOCUS = &H8
WM_ENABLE = &HA
WM_SETREDRAW = &HB
WM_SETTEXT = &HC
WM_GETTEXT = &HD
WM_GETTEXTLENGTH = &HE
WM_PAINT = &HF
WM_CLOSE = &H10
WM_QUERYENDSESSION = &H11
WM_QUERYOPEN = &H13
WM_ENDSESSION = &H16
WM_QUIT = &H12
WM_ERASEBKGND = &H14
WM_SYSCOLORCHANGE = &H15
WM_SHOWWINDOW = &H18
WM_WININICHANGE = &H1A
WM_SETTINGCHANGE = &H1A
WM_DEVMODECHANGE = &H1B
WM_ACTIVATEAPP = &H1C
WM_FONTCHANGE = &H1D
WM_TIMECHANGE = &H1E
WM_CANCELMODE = &H1F
WM_SETCURSOR = &H20
WM_MOUSEACTIVATE = &H21
WM_CHILDACTIVATE = &H22
WM_QUEUESYNC = &H23
WM_GETMINMAXINFO = &H24
WM_PAINTICON = &H26
WM_ICONERASEBKGND = &H27
WM_NEXTDLGCTL = &H28
WM_SPOOLERSTATUS = &H2A
WM_DRAWITEM = &H2B
WM_MEASUREITEM = &H2C
WM_DELETEITEM = &H2D
WM_VKEYTOITEM = &H2E
WM_CHARTOITEM = &H2F
WM_SETFONT = &H30
WM_GETFONT = &H31
WM_SETHOTKEY = &H32
WM_GETHOTKEY = &H33
WM_QUERYDRAGICON = &H37
WM_COMPAREITEM = &H39
WM_GETOBJECT = &H3D
WM_COMPACTING = &H41
WM_COMMNOTIFY = &H44
WM_WINDOWPOSCHANGING = &H46
WM_WINDOWPOSCHANGED = &H47
WM_POWER = &H48
WM_COPYDATA = &H4A
WM_CANCELJOURNAL = &H4B
WM_NOTIFY = &H4E
WM_INPUTLANGCHANGEREQUEST = &H50
WM_INPUTLANGCHANGE = &H51
WM_TCARD = &H52
WM_HELP = &H53
WM_USERCHANGED = &H54
WM_NOTIFYFORMAT = &H55
WM_CONTEXTMENU = &H7B
WM_STYLECHANGING = &H7C
WM_STYLECHANGED = &H7D
WM_DISPLAYCHANGE = &H7E
WM_GETICON = &H7F
WM_SETICON = &H80
WM_NCCREATE = &H81
WM_NCDESTROY = &H82
WM_NCCALCSIZE = &H83
WM_NCHITTEST = &H84
WM_NCPAINT = &H85
WM_NCACTIVATE = &H86
WM_GETDLGCODE = &H87
WM_SYNCPAINT = &H88
WM_NCMOUSEMOVE = &HA0
WM_NCLBUTTONDOWN = &HA1
WM_NCLBUTTONUP = &HA2
WM_NCLBUTTONDBLCLK = &HA3
WM_NCRBUTTONDOWN = &HA4
WM_NCRBUTTONUP = &HA5
WM_NCRBUTTONDBLCLK = &HA6
WM_NCMBUTTONDOWN = &HA7
WM_NCMBUTTONUP = &HA8
WM_NCMBUTTONDBLCLK = &HA9
WM_NCXBUTTONDOWN = &HAB
WM_NCXBUTTONUP = &HAC
WM_NCXBUTTONDBLCLK = &HAD
WM_INPUT = &HFF
WM_KEYFIRST = &H100
WM_KEYDOWN = &H100
WM_KEYUP = &H101
WM_CHAR = &H102
WM_DEADCHAR = &H103
WM_SYSKEYDOWN = &H104
WM_SYSKEYUP = &H105
WM_SYSCHAR = &H106
WM_SYSDEADCHAR = &H107
WM_UNICHAR = &H109
WM_KEYLAST_NT501 = &H109
UNICODE_NOCHAR = &HFFFF
WM_KEYLAST_PRE501 = &H108
WM_IME_STARTCOMPOSITION = &H10D
WM_IME_ENDCOMPOSITION = &H10E
WM_IME_COMPOSITION = &H10F
WM_IME_KEYLAST = &H10F
WM_INITDIALOG = &H110
WM_COMMAND = &H111
WM_SYSCOMMAND = &H112
WM_TIMER = &H113
WM_HSCROLL = &H114
WM_VSCROLL = &H115
WM_INITMENU = &H116
WM_INITMENUPOPUP = &H117
WM_MENUSELECT = &H11F
WM_MENUCHAR = &H120
WM_ENTERIDLE = &H121
WM_MENURBUTTONUP = &H122
WM_MENUDRAG = &H123
WM_MENUGETOBJECT = &H124
WM_UNINITMENUPOPUP = &H125
WM_MENUCOMMAND = &H126
WM_CHANGEUISTATE = &H127
WM_UPDATEUISTATE = &H128
WM_QUERYUISTATE = &H129
WM_CTLCOLORMSGBOX = &H132
WM_CTLCOLOREDIT = &H133
WM_CTLCOLORLISTBOX = &H134
WM_CTLCOLORBTN = &H135
WM_CTLCOLORDLG = &H136
WM_CTLCOLORSCROLLBAR = &H137
WM_CTLCOLORSTATIC = &H138
WM_MOUSEFIRST = &H200
WM_MOUSEMOVE = &H200
WM_LBUTTONDOWN = &H201
WM_LBUTTONUP = &H202
WM_LBUTTONDBLCLK = &H203
WM_RBUTTONDOWN = &H204
WM_RBUTTONUP = &H205
WM_RBUTTONDBLCLK = &H206
WM_MBUTTONDOWN = &H207
WM_MBUTTONUP = &H208
WM_MBUTTONDBLCLK = &H209
WM_MOUSEWHEEL = &H20A
WM_XBUTTONDOWN = &H20B
WM_XBUTTONUP = &H20C
WM_XBUTTONDBLCLK = &H20D
WM_MOUSELAST_5 = &H20D
WM_MOUSELAST_4 = &H20A
WM_MOUSELAST_PRE_4 = &H209
WM_PARENTNOTIFY = &H210
WM_ENTERMENULOOP = &H211
WM_EXITMENULOOP = &H212
WM_NEXTMENU = &H213
WM_SIZING = &H214
WM_CAPTURECHANGED = &H215
WM_MOVING = &H216
WM_POWERBROADCAST = &H218
WM_DEVICECHANGE = &H219
WM_MDICREATE = &H220
WM_MDIDESTROY = &H221
WM_MDIACTIVATE = &H222
WM_MDIRESTORE = &H223
WM_MDINEXT = &H224
WM_MDIMAXIMIZE = &H225
WM_MDITILE = &H226
WM_MDICASCADE = &H227
WM_MDIICONARRANGE = &H228
WM_MDIGETACTIVE = &H229
WM_MDISETMENU = &H230
WM_ENTERSIZEMOVE = &H231
WM_EXITSIZEMOVE = &H232
WM_DROPFILES = &H233
WM_MDIREFRESHMENU = &H234
WM_IME_SETCONTEXT = &H281
WM_IME_NOTIFY = &H282
WM_IME_CONTROL = &H283
WM_IME_COMPOSITIONFULL = &H284
WM_IME_SELECT = &H285
WM_IME_CHAR = &H286
WM_IME_REQUEST = &H288
WM_IME_KEYDOWN = &H290
WM_IME_KEYUP = &H291
WM_MOUSEHOVER = &H2A1
WM_MOUSELEAVE = &H2A3
WM_NCMOUSEHOVER = &H2A0
WM_NCMOUSELEAVE = &H2A2
WM_WTSSESSION_CHANGE = &H2B1
WM_TABLET_FIRST = &H2C0
WM_TABLET_LAST = &H2DF
WM_CUT = &H300
WM_COPY = &H301
WM_PASTE = &H302
WM_CLEAR = &H303
WM_UNDO = &H304
WM_RENDERFORMAT = &H305
WM_RENDERALLFORMATS = &H306
WM_DESTROYCLIPBOARD = &H307
WM_DRAWCLIPBOARD = &H308
WM_PAINTCLIPBOARD = &H309
WM_VSCROLLCLIPBOARD = &H30A
WM_SIZECLIPBOARD = &H30B
WM_ASKCBFORMATNAME = &H30C
WM_CHANGECBCHAIN = &H30D
WM_HSCROLLCLIPBOARD = &H30E
WM_QUERYNEWPALETTE = &H30F
WM_PALETTEISCHANGING = &H310
WM_PALETTECHANGED = &H311
WM_HOTKEY = &H312
WM_PRINT = &H317
WM_PRINTCLIENT = &H318
WM_APPCOMMAND = &H319
WM_THEMECHANGED = &H31A
WM_HANDHELDFIRST = &H358
WM_HANDHELDLAST = &H35F
WM_AFXFIRST = &H360
WM_AFXLAST = &H37F
WM_PENWINFIRST = &H380
WM_PENWINLAST = &H38F
WM_APP = &H8000
WM_USER = &H400
EM_GETSEL = &HB0
EM_SETSEL = &HB1
EM_GETRECT = &HB2
EM_SETRECT = &HB3
EM_SETRECTNP = &HB4
EM_SCROLL = &HB5
EM_LINESCROLL = &HB6
EM_SCROLLCARET = &HB7
EM_GETMODIFY = &HB8
EM_SETMODIFY = &HB9
EM_GETLINECOUNT = &HBA
EM_LINEINDEX = &HBB
EM_SETHANDLE = &HBC
EM_GETHANDLE = &HBD
EM_GETTHUMB = &HBE
EM_LINELENGTH = &HC1
EM_REPLACESEL = &HC2
EM_GETLINE = &HC4
EM_LIMITTEXT = &HC5
EM_CANUNDO = &HC6
EM_UNDO = &HC7
EM_FMTLINES = &HC8
EM_LINEFROMCHAR = &HC9
EM_SETTABSTOPS = &HCB
EM_SETPASSWORDCHAR = &HCC
EM_EMPTYUNDOBUFFER = &HCD
EM_GETFIRSTVISIBLELINE = &HCE
EM_SETREADONLY = &HCF
EM_SETWORDBREAKPROC = &HD0
EM_GETWORDBREAKPROC = &HD1
EM_GETPASSWORDCHAR = &HD2
EM_SETMARGINS = &HD3
EM_GETMARGINS = &HD4
EM_SETLIMITTEXT = EM_LIMITTEXT
EM_GETLIMITTEXT = &HD5
EM_POSFROMCHAR = &HD6
EM_CHARFROMPOS = &HD7
EM_SETIMESTATUS = &HD8
EM_GETIMESTATUS = &HD9
BM_GETCHECK = &HF0
BM_SETCHECK = &HF1
BM_GETSTATE = &HF2
BM_SETSTATE = &HF3
BM_SETSTYLE = &HF4
BM_CLICK = &HF5
BM_GETIMAGE = &HF6
BM_SETIMAGE = &HF7
STM_SETICON = &H170
STM_GETICON = &H171
STM_SETIMAGE = &H172
STM_GETIMAGE = &H173
STM_MSGMAX = &H174
DM_GETDEFID = (WM_USER + 0)
DM_SETDEFID = (WM_USER + 1)
DM_REPOSITION = (WM_USER + 2)
LB_ADDSTRING = &H180
LB_INSERTSTRING = &H181
LB_DELETESTRING = &H182
LB_SELITEMRANGEEX = &H183
LB_RESETCONTENT = &H184
LB_SETSEL = &H185
LB_SETCURSEL = &H186
LB_GETSEL = &H187
LB_GETCURSEL = &H188
LB_GETTEXT = &H189
LB_GETTEXTLEN = &H18A
LB_GETCOUNT = &H18B
LB_SELECTSTRING = &H18C
LB_DIR = &H18D
LB_GETTOPINDEX = &H18E
LB_FINDSTRING = &H18F
LB_GETSELCOUNT = &H190
LB_GETSELITEMS = &H191
LB_SETTABSTOPS = &H192
LB_GETHORIZONTALEXTENT = &H193
LB_SETHORIZONTALEXTENT = &H194
LB_SETCOLUMNWIDTH = &H195
LB_ADDFILE = &H196
LB_SETTOPINDEX = &H197
LB_GETITEMRECT = &H198
LB_GETITEMDATA = &H199
LB_SETITEMDATA = &H19A
LB_SELITEMRANGE = &H19B
LB_SETANCHORINDEX = &H19C
LB_GETANCHORINDEX = &H19D
LB_SETCARETINDEX = &H19E
LB_GETCARETINDEX = &H19F
LB_SETITEMHEIGHT = &H1A0
LB_GETITEMHEIGHT = &H1A1
LB_FINDSTRINGEXACT = &H1A2
LB_SETLOCALE = &H1A5
LB_GETLOCALE = &H1A6
LB_SETCOUNT = &H1A7
LB_INITSTORAGE = &H1A8
LB_ITEMFROMPOINT = &H1A9
LB_MULTIPLEADDSTRING = &H1B1
LB_GETLISTBOXINFO = &H1B2
LB_MSGMAX_501 = &H1B3
LB_MSGMAX_WCE4 = &H1B1
LB_MSGMAX_4 = &H1B0
LB_MSGMAX_PRE4 = &H1A8
CB_GETEDITSEL = &H140
CB_LIMITTEXT = &H141
CB_SETEDITSEL = &H142
CB_ADDSTRING = &H143
CB_DELETESTRING = &H144
CB_DIR = &H145
CB_GETCOUNT = &H146
CB_GETCURSEL = &H147
CB_GETLBTEXT = &H148
CB_GETLBTEXTLEN = &H149
CB_INSERTSTRING = &H14A
CB_RESETCONTENT = &H14B
CB_FINDSTRING = &H14C
CB_SELECTSTRING = &H14D
CB_SETCURSEL = &H14E
CB_SHOWDROPDOWN = &H14F
CB_GETITEMDATA = &H150
CB_SETITEMDATA = &H151
CB_GETDROPPEDCONTROLRECT = &H152
CB_SETITEMHEIGHT = &H153
CB_GETITEMHEIGHT = &H154
CB_SETEXTENDEDUI = &H155
CB_GETEXTENDEDUI = &H156
CB_GETDROPPEDSTATE = &H157
CB_FINDSTRINGEXACT = &H158
CB_SETLOCALE = &H159
CB_GETLOCALE = &H15A
CB_GETTOPINDEX = &H15B
CB_SETTOPINDEX = &H15C
CB_GETHORIZONTALEXTENT = &H15D
CB_SETHORIZONTALEXTENT = &H15E
CB_GETDROPPEDWIDTH = &H15F
CB_SETDROPPEDWIDTH = &H160
CB_INITSTORAGE = &H161
CB_MULTIPLEADDSTRING = &H163
CB_GETCOMBOBOXINFO = &H164
CB_MSGMAX_501 = &H165
CB_MSGMAX_WCE400 = &H163
CB_MSGMAX_400 = &H162
CB_MSGMAX_PRE400 = &H15B
SBM_SETPOS = &HE0
SBM_GETPOS = &HE1
SBM_SETRANGE = &HE2
SBM_SETRANGEREDRAW = &HE6
SBM_GETRANGE = &HE3
SBM_ENABLE_ARROWS = &HE4
SBM_SETSCROLLINFO = &HE9
SBM_GETSCROLLINFO = &HEA
SBM_GETSCROLLBARINFO = &HEB
LVM_FIRST = &H1000 ' ListView messages
TV_FIRST = &H1100 ' TreeView messages
HDM_FIRST = &H1200 ' Header messages
TCM_FIRST = &H1300 ' Tab control messages
PGM_FIRST = &H1400 ' Pager control messages
ECM_FIRST = &H1500 ' Edit control messages
BCM_FIRST = &H1600 ' Button control messages
CBM_FIRST = &H1700 ' Combobox control messages
CCM_FIRST = &H2000 ' Common control shared messages
CCM_LAST = (CCM_FIRST + &H200)
CCM_SETBKCOLOR = (CCM_FIRST + 1)
CCM_SETCOLORSCHEME = (CCM_FIRST + 2)
CCM_GETCOLORSCHEME = (CCM_FIRST + 3)
CCM_GETDROPTARGET = (CCM_FIRST + 4)
CCM_SETUNICODEFORMAT = (CCM_FIRST + 5)
CCM_GETUNICODEFORMAT = (CCM_FIRST + 6)
CCM_SETVERSION = (CCM_FIRST + &H7)
CCM_GETVERSION = (CCM_FIRST + &H8)
CCM_SETNOTIFYWINDOW = (CCM_FIRST + &H9)
CCM_SETWINDOWTHEME = (CCM_FIRST + &HB)
CCM_DPISCALE = (CCM_FIRST + &HC)
HDM_GETITEMCOUNT = (HDM_FIRST + 0)
HDM_INSERTITEMA = (HDM_FIRST + 1)
HDM_INSERTITEMW = (HDM_FIRST + 10)
HDM_DELETEITEM = (HDM_FIRST + 2)
HDM_GETITEMA = (HDM_FIRST + 3)
HDM_GETITEMW = (HDM_FIRST + 11)
HDM_SETITEMA = (HDM_FIRST + 4)
HDM_SETITEMW = (HDM_FIRST + 12)
HDM_LAYOUT = (HDM_FIRST + 5)
HDM_HITTEST = (HDM_FIRST + 6)
HDM_GETITEMRECT = (HDM_FIRST + 7)
HDM_SETIMAGELIST = (HDM_FIRST + 8)
HDM_GETIMAGELIST = (HDM_FIRST + 9)
HDM_ORDERTOINDEX = (HDM_FIRST + 15)
HDM_CREATEDRAGIMAGE = (HDM_FIRST + 16)
HDM_GETORDERARRAY = (HDM_FIRST + 17)
HDM_SETORDERARRAY = (HDM_FIRST + 18)
HDM_SETHOTDIVIDER = (HDM_FIRST + 19)
HDM_SETBITMAPMARGIN = (HDM_FIRST + 20)
HDM_GETBITMAPMARGIN = (HDM_FIRST + 21)
HDM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT
HDM_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT
HDM_SETFILTERCHANGETIMEOUT = (HDM_FIRST + 22)
HDM_EDITFILTER = (HDM_FIRST + 23)
HDM_CLEARFILTER = (HDM_FIRST + 24)
TB_ENABLEBUTTON = (WM_USER + 1)
TB_CHECKBUTTON = (WM_USER + 2)
TB_PRESSBUTTON = (WM_USER + 3)
TB_HIDEBUTTON = (WM_USER + 4)
TB_INDETERMINATE = (WM_USER + 5)
TB_MARKBUTTON = (WM_USER + 6)
TB_ISBUTTONENABLED = (WM_USER + 9)
TB_ISBUTTONCHECKED = (WM_USER + 10)
TB_ISBUTTONPRESSED = (WM_USER + 11)
TB_ISBUTTONHIDDEN = (WM_USER + 12)
TB_ISBUTTONINDETERMINATE = (WM_USER + 13)
TB_ISBUTTONHIGHLIGHTED = (WM_USER + 14)
TB_SETSTATE = (WM_USER + 17)
TB_GETSTATE = (WM_USER + 18)
TB_ADDBITMAP = (WM_USER + 19)
TB_ADDBUTTONSA = (WM_USER + 20)
TB_INSERTBUTTONA = (WM_USER + 21)
TB_ADDBUTTONS = (WM_USER + 20)
TB_INSERTBUTTON = (WM_USER + 21)
TB_DELETEBUTTON = (WM_USER + 22)
TB_GETBUTTON = (WM_USER + 23)
TB_BUTTONCOUNT = (WM_USER + 24)
TB_COMMANDTOINDEX = (WM_USER + 25)
TB_SAVERESTOREA = (WM_USER + 26)
TB_SAVERESTOREW = (WM_USER + 76)
TB_CUSTOMIZE = (WM_USER + 27)
TB_ADDSTRINGA = (WM_USER + 28)
TB_ADDSTRINGW = (WM_USER + 77)
TB_GETITEMRECT = (WM_USER + 29)
TB_BUTTONSTRUCTSIZE = (WM_USER + 30)
TB_SETBUTTONSIZE = (WM_USER + 31)
TB_SETBITMAPSIZE = (WM_USER + 32)
TB_AUTOSIZE = (WM_USER + 33)
TB_GETTOOLTIPS = (WM_USER + 35)
TB_SETTOOLTIPS = (WM_USER + 36)
TB_SETPARENT = (WM_USER + 37)
TB_SETROWS = (WM_USER + 39)
TB_GETROWS = (WM_USER + 40)
TB_SETCMDID = (WM_USER + 42)
TB_CHANGEBITMAP = (WM_USER + 43)
TB_GETBITMAP = (WM_USER + 44)
TB_GETBUTTONTEXTA = (WM_USER + 45)
TB_GETBUTTONTEXTW = (WM_USER + 75)
TB_REPLACEBITMAP = (WM_USER + 46)
TB_SETINDENT = (WM_USER + 47)
TB_SETIMAGELIST = (WM_USER + 48)
TB_GETIMAGELIST = (WM_USER + 49)
TB_LOADIMAGES = (WM_USER + 50)
TB_GETRECT = (WM_USER + 51)
TB_SETHOTIMAGELIST = (WM_USER + 52)
TB_GETHOTIMAGELIST = (WM_USER + 53)
TB_SETDISABLEDIMAGELIST = (WM_USER + 54)
TB_GETDISABLEDIMAGELIST = (WM_USER + 55)
TB_SETSTYLE = (WM_USER + 56)
TB_GETSTYLE = (WM_USER + 57)
TB_GETBUTTONSIZE = (WM_USER + 58)
TB_SETBUTTONWIDTH = (WM_USER + 59)
TB_SETMAXTEXTROWS = (WM_USER + 60)
TB_GETTEXTROWS = (WM_USER + 61)
TB_GETOBJECT = (WM_USER + 62)
TB_GETHOTITEM = (WM_USER + 71)
TB_SETHOTITEM = (WM_USER + 72)
TB_SETANCHORHIGHLIGHT = (WM_USER + 73)
TB_GETANCHORHIGHLIGHT = (WM_USER + 74)
TB_MAPACCELERATORA = (WM_USER + 78)
TB_GETINSERTMARK = (WM_USER + 79)
TB_SETINSERTMARK = (WM_USER + 80)
TB_INSERTMARKHITTEST = (WM_USER + 81)
TB_MOVEBUTTON = (WM_USER + 82)
TB_GETMAXSIZE = (WM_USER + 83)
TB_SETEXTENDEDSTYLE = (WM_USER + 84)
TB_GETEXTENDEDSTYLE = (WM_USER + 85)
TB_GETPADDING = (WM_USER + 86)
TB_SETPADDING = (WM_USER + 87)
TB_SETINSERTMARKCOLOR = (WM_USER + 88)
TB_GETINSERTMARKCOLOR = (WM_USER + 89)
TB_SETCOLORSCHEME = CCM_SETCOLORSCHEME
TB_GETCOLORSCHEME = CCM_GETCOLORSCHEME
TB_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT
TB_GETUNICODEFORMAT = CCM_GETUNICODEFORMAT
TB_MAPACCELERATORW = (WM_USER + 90)
TB_GETBITMAPFLAGS = (WM_USER + 41)
TB_GETBUTTONINFOW = (WM_USER + 63)
TB_SETBUTTONINFOW = (WM_USER + 64)
TB_GETBUTTONINFOA = (WM_USER + 65)
TB_SETBUTTONINFOA = (WM_USER + 66)
TB_INSERTBUTTONW = (WM_USER + 67)
TB_ADDBUTTONSW = (WM_USER + 68)
TB_HITTEST = (WM_USER + 69)
TB_SETDRAWTEXTFLAGS = (WM_USER + 70)
TB_GETSTRINGW = (WM_USER + 91)
TB_GETSTRINGA = (WM_USER + 92)
TB_GETMETRICS = (WM_USER + 101)
TB_SETMETRICS = (WM_USER + 102)
TB_SETWINDOWTHEME = CCM_SETWINDOWTHEME
↧
Convert API Object to Standard Object
When an object, such as a Progressbar, is pulled out of a Toolbox, the standard "Name" is "Progressbar1", then "Progressbar2", 3, etc. After this a person could use "Progressbar1.forecolor = somecolor" or change any other property or method for the Progressbar.
When an object is made via CreateWindowEx (example: qwprogressbar = CreateWindowEx(0, PROGRESS_CLASS, vbNullString, WS_CHILD Or WS_VISIBLE Or PBS_SMOOTH, 15, 230, 250, 20, hwnd, 0, App.hInstance, ByVal 0) ), a handle is created, in this case "qwprogressbar".
How can an object that is created using "CreateWindowEx" be given a "Name" so it acts like an object that was pulled from a Toolbox so the properties and methods could be accessed the same way as if they had been pulled from a toolbox? Is this even possible? Thanks in advance for any help.
When an object is made via CreateWindowEx (example: qwprogressbar = CreateWindowEx(0, PROGRESS_CLASS, vbNullString, WS_CHILD Or WS_VISIBLE Or PBS_SMOOTH, 15, 230, 250, 20, hwnd, 0, App.hInstance, ByVal 0) ), a handle is created, in this case "qwprogressbar".
How can an object that is created using "CreateWindowEx" be given a "Name" so it acts like an object that was pulled from a Toolbox so the properties and methods could be accessed the same way as if they had been pulled from a toolbox? Is this even possible? Thanks in advance for any help.
↧