Quantcast
Channel: VBForums - CodeBank - Visual Basic 6 and earlier
Viewing all 1530 articles
Browse latest View live

[VB6] QuadTree

$
0
0
Hi
this is a Class to implement (points) QuadTree for 2D collision detection.

Suggestions and improvements are welcome (especially regarding speed)


(Used to use it, this demo requires vbRichClient (for Draw). However, you can easily modify a few lines of code to do without it)

Inspired by:
Attached Files

AES Demo

$
0
0
Attached is a demo of AES encryption/decryption using CNG. The default uses a key size of 128, but there is provision for 192 and 256. The HMAC is SHA256, which is what is used in TLS 1.2.

The PreMaster Secret or Key Exchange in this case was randomly generated as were the Server and Client Randoms. The ones currently being used were taken from an actual session shown here:

http://www.yellowhead.com/TLS_Handshake5.htm

The above page shows a packet capture for a TLS session using the mandatory TLS 1.2 cipher suite (002F - TLS_RSA_WITH_AES_128_CBC_SHA). The Pre-Master Secret could also have been the Agreed Secret generated by a Diffie-Hellman Ephemeral process. The Master Keys are generated from all 3 values, and differ depending on whether it is for the Server or the Client. The default is the Client process and produces:
ReadKey:
63 4C 69 C0 A4 1E 24 40 11 F8 CA 37 21 47 9A 92
ReadMAC:
0A 8E 88 F1 1F 51 12 FA 80 05 9A 79 72 A1 32 18
46 7A D4 B5
ReadIV:
DF 9D E1 74 68 60 55 19 26 02 00 00 66 00 28 00
WriteKey:
03 2C 9E EA 56 F4 C9 6F AC 12 01 47 82 BB FE F8
WriteMAC:
63 62 57 B8 EE 53 F9 7F 37 4F 0A 24 B0 5E 86 04
A3 FB A8 FA
WriteIV:
06 68 62 BE 20 46 10 12 AE 3B 36 F7 12 47 DA FD

PRF1_2 is used to create the Master Secret from Pre-Master Secret, Client Random, & Server Random. The Client & Server Randoms are then switched, and PRF1_2 is again used to create the Master Hash from the Master Secret, Server Random, & Client Random. The various keys are then extracted from the Master Hash.

That's the hard part. The easy part is the actual encryption and decryption. If you are wondering what the IV variable is used for, it stands for Initialization Vector, and is necessary for any Block Algorithm. Block Algorithms use a repeating Xor (exclusive or) routine of the Block Length to create the encrypted value, and that repetition makes it vulnerable to being hacked when a known value is being encrypted. The Initialization Vector resolves that issue. As well, that repetition can make the encrypted value longer than the original value, necessitating Block Padding.

This demo uses the full Unicode characters, which for ASCII (English) doubles the length of the encrypted value. You can alternatively use every second byte, or the UTF8 value. The difficulty with UTF8 is that there is no enforced standard for detecting it in an encrypted value.

J.A. Coutts
Attached Images
 
Attached Files

VB6 MultiProcessing (StdExe-IPC via SharedMemory)

$
0
0
This demonstrates, how one can implement robust, asynchronous Workers in VB6 -
by using a (cross-process) SharedMemory-approach (which is one of the common IPC-mechanisms).

For convenient usage, the more complex stuff (the MemoryMapping- as well as the CreateProcess-APIs),
are encapsulated in two generic "Drop-In"-Classes (cIPCMaster and cIPCWorker).

Those Classes can be used either "split-up" (in separate VB6-Projects for Master and Worker) -
but also "all-in-one" (when the same Project - or Process - is used to act as Master and Worker both).

The latter case (using an "all-in-one"-Project), is the most convenient for developing/testing.
Here the Worker-Process is "shelled" against the same ExeName as the Main- (or Master-) Project,
using a simple "forking" in Sub Main() ... (as shown below from the content of Demo1 modMain.bas):
Code:

Option Explicit

Sub Main() 'Process-Startup-Forking
  If Len(Trim$(Command$)) = 0 Then 'no Cmd-Arg was passed (it was started as the Master-Process)
    fMaster.Show '... so we simply startup the Main-Form
   
  Else 'it was started as a WorkerProcess (pass the CommandLine-Arg into the WorkerRoutine)
    EnterWorkerLoop New cIPCWorker, Trim$(Command$)
  End If
End Sub

Above, the blue-colored call represents the "master-fork-path" to your normal "GUI-Project-Code"
(entered when no Commandline-Param was passed to your Executable).

And as the magenta-colored routine-name (in the "worker-fork-path") suggests, the upstarting worker is not fired up
like in an old "classic WebServer-CGI-call" (where the Process exits, after only a single Job was performed).

Instead the current mechanism is implemented in a way, that the WorkerProcess is fired up once -
and then enters an "IDLE-loop" (waiting for Jobs, provided by the Master-Process later).
This way one of the disadvantages of MultiProcessing (the higher Startup-Costs, compared to MultiThreading) is avoided.

The advantages of doing MultiProcessing instead of threading are:
- no typelibs, no extra-Dlls are needed
- in the IDE (after compiling the same Project), the asynchronous workers will behave the same way as in the compiled binary
- a hard terminate of a worker is possible in a stable and "residue-free" manner (though graceful termination-support is of course built-in)
- the communication between Master and Worker(s) happens in an absolute "non-blocking" way

To explain the last point above a bit more... "non-blocking" means, that neither Post- or SendMessage-calls are involved
(as in VB6-OleBased-Communications between "threaded Apartments", where Events, raised from the Workers will block the Main-Thread) -
nor are there other mechanisms in play like Mutexes or CriticalSections, which are normally used in conjunction with shared memory...

Instead the Demo shows, how "state-machine-based" communication (using the shared mem-area) can be implemented.

The approach is extremely robust, completely IDE- and crash-safe, and "cleans up after itself" under any circumstances:
- upstarted Worker-Processes will automatically close, when the Master-Class goes out of scope
- you can even use the IDE-stop-button, whilst asynchronous workers are "deep within a Job" (worker-processes will autoclose nevertheless)

There is also not a single thing, which is "forbidden to use" in the workers (like in many of the threading-approaches for VB6)...

The Zip below comes with 3 Demo-Folders (a simple one to get up to speed - and two "medium-difficult" ones for MandelBrot-rendering).

Ok, here is, what the MandelBrot-Demos will produce (using two Workers, independent from the Main-App):


And here's the Demo-Zip: IPCSharedMem.zip

Have fun...

Olaf
Attached Files

Auto-Complete RichTextBox

$
0
0
Whipped this up this afternoon (bored!) so it may not be perfect. It was mentioned/requested here:

http://www.vbforums.com/showthread.p...the-first-word

It's a little different from the usual auto-complete textboxes in terms of how the user interacts with it and it's possible to auto-complete any part of a string, not just from the start.

It's basically just a small class that is initialised by setting a reference to a RichText Box and an ADO recordset.

Have a play and modify as you see fit. I have no desire to do any more with it as I don't use ADO...
Attached Images
 
Attached Files

[VB6] - Module for working with multithreading.

$
0
0
Hello everyone!

I present the module for working with multithreading in VB6 for Standard EXE projects. This module is based on this solution with some bugfixing and the new functionality is added. The module doesn't require any additional dependencies and type libraries, works as in the IDE (all the functions work in the main thread) as in the compiled form.


To start working with the module, you need to call the Initialize function, which initializes the necessary data (it initializes the critical sections for exclusive access to the heaps of marshalinig and threads, modifies VBHeader (here is description), allocates a TLS slot for passing the parameters to the thread).

The main function of thread creation is vbCreateThread, which is an analog of the CreateThread function.

Code:

' // Create a new thread
Public Function vbCreateThread(ByVal lpThreadAttributes As Long, _
                              ByVal dwStackSize As Long, _
                              ByVal lpStartAddress As Long, _
                              ByVal lpParameter As Long, _
                              ByVal dwCreationFlags As Long, _
                              ByRef lpThreadId As Long, _
                              Optional ByVal bIDEInSameThread As Boolean = True) As Long

The function creates a thread and calls the function passed in the lpStartAddress parameter with the lpParameter parameter.
In the IDE, the call is reduced to a simple call by the pointer implemented through DispCallFunc. In the compiled form, this function works differently. Because a thread requires initialization of project-specific data and initialization of the runtime, the parameters passed to lpStartAddress and lpParameter are temporarily stored into the heap by the PrepareData function, and the thread is created in the ThreadProc function, which immediately deals with the initialization and calling of the user-defined function with the user parameter. This function creates a copy of the VBHeader structure via CreateVBHeaderCopy and changes the public variable placement data in the VbPublicObjectDescriptor.lpPublicBytes, VbPublicObjectDescriptor.lpStaticBytes structures (BTW it wasn't implemented in the previous version) so that global variables are not affected during initialization. Further, VBDllGetClassObject calls the FakeMain function (whose address is written to the modified VBHeader structure). To transfer user parameters, it uses a TLS slot (since Main function doesn't accept parameters, details here). In FakeMain, parameters are directly extracted from TLS and a user procedure is called. The return value of the function is also passed back through TLS. There is one interesting point related to the copy of the header that wasn't included in the previous version. Because the runtime uses the header after the thread ends (with DLL_THREAD_DETACH), we can't release the header in the ThreadProc procedure, therefore there will be a memory leak. To prevent the memory leaks, the heap of fixed size is used, the headers aren't cleared until there is a free memory in this heap. As soon as the memory ends (and it's allocated in the CreateVBHeaderCopy function), resources are cleared. The first DWORD of header actually stores the ID of the thread which it was created in and the FreeUnusedHeaders function checks all the headers in the heap. If a thread is completed, the memory is freed (although the ID can be repeated, but this doesn't play a special role, since in any case there will be a free memory in the heap and if the header isn't freed in one case, it will be released later). Due to the fact that the cleanup process can be run immediately from several threads, access to the cleanup is shared by the critical section tLockHeap.tWinApiSection and if some thread is already cleaning up the memory the function will return True which means that the calling thread should little bit waits and the memory will be available.

The another feature of the module is the ability to initialize the runtime and the project and call the callback function. This can be useful for callback functions that can be called in the context of an arbitrary thread (for example, InternetStatusCallback). To do this, use the InitCurrentThreadAndCallFunction and InitCurrentThreadAndCallFunctionIDEProc functions. The first one is used in the compiled application and takes the address of the callback function that will be called after the runtime initialization, as well as the parameter to be passed to this function. The address of the first parameter is passed to the callback procedure to refer to it in the user procedure:

Code:

' // This function is used in compiled form
Public Function CallbackProc( _
                ByVal lThreadId As Long, _
                ByVal sKey As String, _
                ByVal fTimeFromLastTick As Single) As Long
    ' // Init runtime and call CallBackProc_user with VarPtr(lThreadId) parameter
    InitCurrentThreadAndCallFunction AddressOf CallBackProc_user, VarPtr(lThreadId), CallbackProc
End Function

' // Callback function is called by runtime/window proc (in IDE)
Public Function CallBackProc_user( _
                ByRef tParam As tCallbackParams) As Long

End Function

CallBackProc_user will be called with the initialized runtime.

This function doesn't work in the IDE because in the IDE everything works in the main thread. For debugging in the IDE the function InitCurrentThreadAndCallFunctionIDEProc is used which returns the address of the assembler thunk that translates the call to the main thread and calls the user function in the context of the main thread. This function takes the address of the user's callback function and the size of the parameters in bytes. It always passes the address of the first parameter as a parameter of a user-defined function. I'll tell you a little more about the work of this approach in the IDE. To translate a call from the calling thread to the main thread it uses a message-only window. This window is created by calling the InitializeMessageWindow function. The first call creates a WindowProc procedure with the following code:

Code:

    CMP DWORD [ESP+8], WM_ONCALLBACK
    JE SHORT L
    JMP DefWindowProcW
L:  PUSH DWORD PTR SS:[ESP+10]
    CALL DWORD PTR SS:[ESP+10]
    RETN 10

As you can see from the code, this procedure "listens" to the WM_ONCALLBACK message which contains the parameter wParam - the function address, and in the lParam parameters. Upon receiving this message it calls this procedure with this parameter, the remaining messages are ignored. This message is sent just by the assembler thunk from the caller thread. Futher, a window is created and the handle of this window and the code heap are stored into the data of the window class. This is used to avoid a memory leak in the IDE because if the window class is registered once, then these parameters can be obtained in any debugging session. The callback function is generated in InitCurrentThreadAndCallFunctionIDEProc, but first it's checked whether the same callback procedure has already been created (in order to don't create the same thunk). The thunk has the following code:

Code:

LEA EAX, [ESP+4]
PUSH EAX
PUSH pfnCallback
PUSH WM_ONCALLBACK
PUSH hMsgWindow
Call SendMessageW
RETN lParametersSize

As you can see from the code, during calling a callback function, the call is transmitted via SendMessage to the main thread. The lParametersSize parameter is used to correctly restore the stack.

The next feature of the module is the creation of objects in a separate thread, and you can create them as private objects (the method is based on the code of the NameBasedObjectFactory by firehacker module) as public ones. To create the project classes use the CreatePrivateObjectByNameInNewThread function and for ActiveX-public classes CreateActiveXObjectInNewThread and CreateActiveXObjectInNewThread2 ones. Before creating instances of the project classes you must first enable marshaling of these objects by calling the EnablePrivateMarshaling function. These functions accept the class identifier (ProgID / CLSID for ActiveX and the name for the project classes) and the interface identifier (IDispatch / Object is used by default). If the function is successfully called a marshaled object and an asynchronous call ID are returned. For the compiled version this is the ID of thread for IDE it's a pointer to the object. Objects are created and "live" in the ActiveXThreadProc function. The life of objects is controlled through the reference count (when it is equal to 1 it means only ActiveXThreadProc refers to the object and you can delete it and terminate the thread).
You can call the methods either synchronously - just call the method as usual or asynchronously - using the AsynchDispMethodCall procedure. This procedure takes an asynchronous call ID, a method name, a call type, an object that receives the call notification, a notification method name and the list of parameters. The procedure copies the parameters to the temporary memory, marshals the notification object, and sends the data to the object's thread via WM_ASYNCH_CALL. It should be noted that marshaling of parameters isn't supported right now therefore it's necessary to transfer links to objects with care. If you want to marshal an object reference you should use a synchronous method to marshal the objects and then call the asynchronous method. The procedure is returned immediately. In the ActiveXThreadProc thread the data is retrieved and a synchronous call is made via MakeAsynchCall. Everything is simple, CallByName is called for the thread object and CallByName for notification. The notification method has the following prototype:

Code:

Public Sub CallBack (ByVal vRet As Variant)
, where vRet accepts the return value of the method.

The following functions are intended for marshaling: Marshal, Marshal2, UnMarshal, FreeMarshalData. The first one creates information about the marshaling (Proxy) of the interface and puts it into the stream (IStream) that is returned. It accepts the interface identifier in the pInterface parameter (IDispatch / Object by default). The UnMarshal function, on the contrary, receives a stream and creates a Proxy object based on the information in the stream. Optionally, you can release the thread object. Marshal2 does the same thing as Marshal except that it allows you to create a Proxy object many times in different threads. FreeMarshalData releases the data and the stream accordingly.
If, for example, you want to transfer a reference to an object between two threads, it is enough to call the Marshal / UnMarshal pair in the thread which created the object and in the thread that receives the link respectively. In another case, if for example there is the one global object and you need to pass a reference to it to the multiple threads (for example, the logging object), then Marshal2 is called in the object thread, and UnMarshal with the bReleaseStream parameter is set to False is called in client threads. When the data is no longer needed, FreeMarshalData is called.

The WaitForObjectThreadCompletion function is designed to wait for the completion of the object thread and receives the ID of the asynchronous call. It is desirable to call this function always at the end of the main process because an object thread can somehow interact with the main thread and its objects (for example, if the object thread has a marshal link to the interface of the main thread).

The SuspendResume function is designed to suspend/resume the object's thread; bSuspend determines whether to sleep or resume the thread.

In addition, there are also several examples in the attacment of working with module:
  1. Callback - the project demonstrates the work with the callback-function periodically called in the different threads. Also, there is an additional project of native dll (on VB6) which calls the function periodically in the different threads;
  2. JuliaSet - the Julia fractal generation in the several threads (user-defined);
  3. CopyProgress - Copy the folder in a separate thread with the progress of the copy;
  4. PublicMarshaling - Creating public objects (Dictionary) in the different threads and calling their methods (synchronously / asynchronously);
  5. PrivateMarshaling - Creating private objects in different threads and calling their methods (synchronously / asynchronously);
  6. MarshalUserInterface - Creating private objects in different threads and calling their methods (synchronously / asynchronously) based on user interfaces (contains tlb and Reg-Free manifest).


The module is poorly tested so bugs are possible. I would be very glad to any bug-reports, wherever possible I will correct them.
Thank you all for attention!

Best Regards,
The trick.
Attached Files

Viewing Token Privileges

$
0
0
Privileges can be required to access system resources, and it can be a nuisance when an API call fails because a privilege is not available. This application displays the privileges available to the process token for the current logged on User.
If run as administrator, it will show the elevated privileges. In general, if a privilege is required for an API function, the application should be running with elevated credentials as a standard user has very few privileges. The application may also need to enable the privilege, before the API function is called.

For example there are a number of API functions to create a process, and only some of these require privileges:

  • CreateProcessWithTokenW
    must have the SE_IMPERSONATE_NAME privilege.
  • CreateProcessAsUser
    must have the SE_INCREASE_QUOTA_NAME privilege and may require the SE_ASSIGNPRIMARYTOKEN_NAME privilege if the token is not assignable
  • CreateProcessWithLogonW
    requires no special privileges as the new process runs in the security context of the Logon User
  • CreateProcess
    requires no special privileges as the new process runs in the security context of the calling process

The following screen image illustrates the privileges available for an elevated user.
Name:  Token Privileges.png
Views: 105
Size:  115.5 KB

From this example, the elevated user can call the CreateProcessWithTokenW, but before calling the CreateProcessAsUser, the application must first enable the SeIncreaseQuotaPrivilege. But this API would still return unsuccessful if the token is not assignable, because this elevated user does not have the SeAssignedPrimaryTokenPrivilege.

This application also has code to enable and disable a privilege.

The attached project also includes more detailed information on this application.
TokenPrivilege.zip
Attached Images
 
Attached Files

Encrypting passwords with CryptProtectMemory

$
0
0
Protecting passwords in memory
In this age of security awareness, it is important to protect any passwords or other sensitive data that may be used by applications and written to the computer memory. The protection is twofold, firstly by encrypting the sensitive data, and secondly by erasing any memory that might have contained unprotected sensitive data, before the variable goes out of scope.

The Windows API includes the CryptProtectMemory function to encrypt data in memory. For example, one might request user credentials using the API CredUIPromptForWindowsCredentials, and then use these credentials to launch an application using the API CreateProcessWithLogonW function. Between these two functions, the password would be held in a variable and hence the password is somewhere in the computer memory. The password should be protected by encrypting the password as soon as it is returned from the API, then erasing the variable that held the password before it goes out of scope. Just before the CreateProcessWithLogonW function is called the password can be decrypted into a variable, the variable passed to the api and then erase the memory used by this variable.

Sample Application
The attached application demonstrates the usage of the CryptProtectMemory function to encrypt and decrypt data. This application does not involve any passwords, but demonstrates the process of encrypting a text string, and decrypting the text, and a simple method to erase the memory used by a string variable. Erasing a string could be tricky as in VB normal string manipulation assigns a string to a new memory, leaving the original string as free memory. One simply solution to erase the actual data in memory is to use the mid$ statement:
Mid$(sData, 1, Len(sData)) = String$(Len(sData), vbNullChar)
This writes zeroes to the string without changing its location in memory.

The application consists of a form to enter the text, a button to encrypt the text and show the result as hex bytes, and then to decrypt the encrypted text to recover the original text.

Name:  CryptProtectMemory.png
Views: 83
Size:  9.4 KB
In this application the encrypted data is converted into a hex string, which makes it easy to inspect the result and compare the different encryptions. In normal usage the encrypted data should not be exposed in this way.

The CryptProtectMemory has three different flags for setting different types of encryption and this defines the scope for which the encrypted data can be shared.

Comparing the different encryption settings

The Windows API CryptProtectMemory has 3 flag settings for the type of encryption.
· CRYPTPROTECTMEMORY_SAME_PROCESS
· CRYPTPROTECTMEMORY_SAME_LOGON
· CRYPTPROTECTMEMORY_CROSS_PROCESS

This application provides radio buttons to select the type of encryption, and the text alongside the Decrypt button will show the scope of the selected option.

Explore the implications of these different settings by running multiple instances of this application. Use the run as administrator to create an instance with a different logon session.

Additional documentation is included in the attached project files
CryptProtectMemory.zip
Attached Images
 
Attached Files

Scintilla Source Code editor OCX for VB

$
0
0
I noticed the board didn't have much on the Scintilla source code editor so wanted to make sure a copy of this got saved.

Scintilla is a source code editor component that includes source code highlighting, code folding, line numbering, bookmarks, built in intellisense etc. It is a great control if you want to create a source code editor or debugger UI.

Name:  screenshot.jpg
Views: 140
Size:  14.5 KB

Its a free component written in C and builds as SciLexer.dll. You can download the source files here:

https://www.scintilla.org/

The source attached here, scivb2.ocx, is a vb6 control that makes using it quite easy. This is an update to Stewarts great scivb.ocx control that is part of his cEditXP souce code editor.

http://www.planet-source-code.com/vb...66207&lngWId=1

I spent some time inside of it and adapted it for what I needed so I could use it as a debugger UI You can see an example of it in action here:

https://www.youtube.com/watch?v=nSr1-OugQ1M

I have attached a copy of the ocx source. I have been using this for several years now and has proven stable. Any updates will be in the git repo below.

https://github.com/dzzie/scivb2

public methods:
Code:

'Events
Event NewLine()
Event MouseDwellEnd(lline As Long, Position As Long)
Event MouseDwellStart(lline As Long, Position As Long)
Event MarginClick(lline As Long, Position As Long, margin As Long, modifiers As Long)
Event AutoCSelection(Text As String)                        'Auto Completed selected
Event CallTipClick(Position As Long)                        'Clicked a calltip
Event UserListSelection(listType As Long, Text As String)  'Selected AutoComplete
Event LineChanged(Position As Long)
Event OnModified(Position As Long, modificationType As Long)
Event DoubleClick()
Event MouseUp(Button As Integer, Shift As Integer, x As Long, y As Long)
Event MouseDown(Button As Integer, Shift As Integer, x As Long, y As Long)
Event key(ch As Long, modifiers As Long)
Event KeyUp(KeyCode As Long, Shift As Long)
Event KeyDown(KeyCode As Long, Shift As Long)
Event DebugMsg(Msg As String)
Event KeyPress(Char As Long)
Event AutoCompleteEvent(className As String)

'Properties
Property FoldComment() As Boolean
Property FoldAtElse() As Boolean
Property FoldMarker() As FoldingStyle
Property Folding() As Boolean    'If true folding will be automatically handled.
Property DisplayCallTips() As Boolean  'If this is set to true then calltips will be displayed.  To use this you must also use <B>LoadAPIFile</b> to load an external API file which contains simple instructions to the editor on what calltips to display.
Property SelFore() As OLE_COLOR  'The allows you to control the fore color of the selected color.
Property SelBack() As OLE_COLOR  'This allow's you to set the backcolor for selected text.
Property WordWrap() As Boolean 'If set to true the document will wrap lines which are longer than itself.  If false then it will dsiplay normally.
Property ShowFlags() As Boolean  'If this is true the second gutter will be displayed and Flags/Bookmarks will be displayed.
Property isDirty() As Boolean  'This is a read only property.  It allows you to get the modified status of the Scintilla window.
Property ReadOnly() As Boolean  'This property allows you to set the readonly status of Scintilla.  When in readonly you can scroll the document, but no editing can be done.
Property LineNumbers() As Boolean    'If this is set to true then the first gutter will be visible and display line numbers.  If this is false then the first gutter will remain hidden.
Property ContextMenu() As Boolean    'If set to true then the default Scintilla context menu will be displayed when a user right clicks on the window.  If this is set to false then no context menu will be displayed.  If you are utilizing a customer context menu then this should be set to false.
Property AutoCompleteString() As String  'This store's the list which autocomplete will use.  Each word needs to be seperated by a space.
Property IndentWidth() As Long  'This controls the number of spaces Tab will indent.  IndentWidth only applies if <B>TabIndents</b> is set to false.
Property BackSpaceUnIndents() As Boolean 'If tabindents is set to false, and BackSpaceUnIndents is set to true then the backspaceunindents will remove the same number of spaces as tab inserts.  If it's set to false then it will work normally.
Property UseTabIndents() As Boolean 'If this is true tab inserts indent characters.  If it is set to false tab will insert spaces.
Property useTabs() As Boolean
Property ShowIndentationGuide() As Boolean  'If true indention guide's will be displayed.
Property MaintainIndentation() As Boolean 'If this is set to true the editor will automatically keep the previous line's indentation.
Property HighLightActiveLine() As Boolean    'When set to true the active line will be highlighted using the color selected from LineBackColor.
Property ActiveLineBackColor() As OLE_COLOR    'Allows you to control the backcolor of the active line.
Property SelText() As String 'Allows you to get and set the seltext of the scintilla window.
Property Text() As String    'Allows you to get and set the text of the scintilla window.
Property SelLength() As Long
Property SelEnd() As Long
Property SelStart() As Long
Property codePage() As SC_CODETYPE
Property TotalLines() As Long
Property VisibleLines() As Long
Property FirstVisibleLine() As Long
Property AutoCloseQuotes() As Boolean    'When set to true quotes will automatically be closed.
Property AutoCloseBraces() As Boolean    'When this is set to true braces <B>{, [, (</b> will be closed automatically.
Property Version() As String
Property currentHighlighter() As String
Property sciHWND() As Long
Friend Property Let ReplaceFormActive(x As Boolean)

'Methods
Function isMouseOverCallTip() As Boolean
Sub LockEditor(Optional locked As Boolean = True)
Function WordUnderMouse(pos As Long, Optional ignoreWhiteSpace As Boolean = False) As String
Sub ShowGoto()
Sub ShowAbout()
Function ShowFindReplace() As Object
Function FindNext(Optional wrap As Boolean = False) As Long
Function Find(sSearch As String, _
Function FindAll(sSearch As String, _
Function ReplaceAll(strSearchFor As String, _
Function ReplaceText(strSearchFor As String, _
Sub MarkAll(strFind As String)
Sub SetMarker(iLine As Long, Optional iMarkerNum As Long = 2)
Sub DeleteAllMarkers(Optional marknum As Long = 2)
Sub PrevMarker(lline As Long, Optional marknum As Long = 2)
Sub NextMarker(lline As Long, Optional marknum As Long = 2)
Sub DeleteMarker(iLine As Long, Optional marknum As Long = 2)
Sub ToggleMarker(Optional line As Long = -1)
Sub FoldAll()
Sub ShowCallTip(strVal As String)
Sub StopCallTip()
Function AddCallTip(functionPrototype As String)
Function LoadCallTips(strFile As String) As Long
Function LoadFile(strFile As String) As Boolean
Function SaveFile(strFile As String) As Boolean
Function PreviousWord() As String
Function CurrentWord() As String
Sub ShowAutoComplete(strVal As String)
Function GetCaretInLine() As Long
Function CurrentLine() As Long
Sub SetCurrentPosition(lval As Long)
Function PositionFromLine(lline As Long) As Long
Sub ClearUndoBuffer()
Function SelectLine() As Long
Function SelectAll() As Long
Function Paste() As Long
Function Copy() As Long
Function Cut() As Long
Function Undo() As Long
Function Redo() As Long
Function SetFocus() As Long
Function GotoCol(Column As Long) As Long
Sub GotoLineColumn(iLine As Long, iCol As Long)
Function GotoLine(line As Long) As Long
Function GetLineText(ByVal lline As Long) As String
Function FileExists(strFile As String) As Boolean
Function FolderExists(path) As Boolean
Sub GotoLineCentered(ByVal line As Long, Optional selected As Boolean = True)
Function hilightWord(sSearch As String, Optional color As Long = 0, Optional compare As VbCompareMethod = vbTextCompare) As Long
Sub hilightClear()
Sub UncommentBlock()
Sub CommentBlock()
Function ExportToHTML(filePath As String) As Boolean
Function LoadHighlightersDir(dirPath As String) As Long
Function HighlighterForExtension(fPath As String) As String
Function LoadHighlighter(filePath As String, Optional andSetActive As Boolean = True) As Boolean
Function SetHighlighter(langName As String) As Boolean

Attached Images
 
Attached Files

Hexeditor OCX control

$
0
0
A hexeditor/viewer is another commonly needed component. Here is one I have been using for a number of years now.

Name:  screenshot.jpg
Views: 94
Size:  89.9 KB

The core of this one was taken from a standalone hexeditor written by Rang3r and released on psc in 2001

http://www.Planet-Source-Code.com/vb...34729&lngWId=1

It has been converted into an OCX and includes common functions such as load from string/bytearray/file,
ability to copy hexcodes, search, and extract strings. It also has good performance on large files.

The ocx also includes a public class so you can launch a hexeditor on its own form without having to host it
on a dedicated form of your own.

Any updates will be in the git repo here:

https://github.com/dzzie/hexed

public methods:
Code:


Property BookMarks() As Collection
Public Property hWndAscii() As Long
Public Property hWndCanvas() As Long
Public Property hwnd() As Long
Public Property AsciiBGColor() As Long
Public Property HexBGColor() As Long
Public Property MarginBGColor() As Long
Public Property MarginColor() As Long
Public Property AsciiColor() As Long
Public Property EvenColor() As Long
Public Property OddColor() As Long
Public Property ModColor() As Long
Public Property Font() As StdFont
Public Property IsDirty() As Boolean
Public Property DataLength() As Long
Public Property SelLength() As Long
Public Property SelStart() As Long
Public Property SelTextAsHexCodes(Optional prefix As String = Empty) As String
Public Property SelText() As String
Public Property Columns() As Long
Property ReadChunkSize() As Long
Property LoadedFile() As String
Property VisibleLines() As Long
Property CurrentPosition() As Long
Public Sub GotoNextBookmark()
Public Sub ToggleBookmark(ByVal Pos As Long)
Public Sub ShowBookMarks()
Public Function FileSize() As Long
Public Function GetDataChunk(ByVal Pos As Long) As String
Public Function GetData(ByVal Pos As Long) As Byte
Public Sub Scroll(ByVal Amount As Long)
Public Sub Save()
Public Sub SaveAs(Optional fpath As String = Empty, Optional defaultfName As String)
Public Sub FullView()
Public Sub HexView()
Public Sub AsciiView()
Public Function LoadFile(fpath As String, Optional ViewOnly As Boolean = True) As Boolean
Function FileExists(path As String) As Boolean
Function FolderExists(path As String) As Boolean
Public Function LoadByteArray(bArray As Variant, Optional ViewOnly As Boolean = True) As Boolean
Public Function LoadString(data As String, Optional ViewOnly As Boolean = True) As Boolean
Public Sub DeleteData(ByVal Pos As Long, ByVal length As Long)
Public Sub OverWriteData(ByVal Pos As Long, data() As Byte)
Public Sub InsertData(ByVal Pos As Long, data() As Byte)
Public Sub ShowInsert()
Public Sub CopyData(ByVal Pos As Long, ByVal length As Long)
Public Sub DoUndo()
Public Sub Refresh()
Public Sub DoCut()
Public Function Strings(Optional minLen As Long = 7, Optional unicode As Boolean = False) As String()
Public Sub SelectAll()
Public Sub DoPaste()
Public Sub DoPasteOver()
Public Sub DoDelete()
Public Sub DoCopy()
Public Sub ShowGoto()
Public Sub scrollTo(ByVal Pos As Long)
Public Sub ShowFind()
Public Function Search(match As String, Optional isUnicode As Boolean = False, Optional caseSensitive As Boolean = False) As String()
Public Function ShowHelp()
Public Function ShowAbout()
Public Function ShowOpen(Optional initDir As String, Optional ViewOnly As Boolean = False) As Boolean

Attached Images
 
Attached Files

[VB6] - PE parsing library

$
0
0
This is a set of classes for parsing PE files.

Exposes most commonly needed fields such as optional header, imports, exports, relocations, resources, sections, etc.
Includes a couple extras such as a built in offset calculator form, file properties class, hashing class, and asm/disasm classes (if you have the C olly.dll)

Stable source attached, any updates will be in git here:

https://github.com/dzzie/libs/tree/master/pe_lib2

If you need to work on x64 binaries I do have a newer version but it has another ActiveX dependency for working
with x64 numbers.

https://github.com/dzzie/libs/tree/master/pe_lib3

If you have to work with .NET structures check out vbgamers work at the link below.
I havent played with this section of code yet but will eventually include it in my libs:

https://github.com/VBGAMER45/Semi-VB...r/modVBNET.bas
Attached Files

VB6 - Hash10

$
0
0
Now this one makes a lot of sense. I accidentally ran across it while searching for something else.

https://docs.microsoft.com/en-us/win...ypt-bcrypthash

BCryptHash performs a single hash computation. This is a convenience function that wraps calls to BCryptCreateHash, BCryptHashData, BCryptFinishHash, and BCryptDestroyHash.

Attached is the updated Hash program I previously posted.

Unfortunately, it only works in Windows 10. If you try to run it in Vista or Win 8.1, you will get this error:

Run-time error '453':
Can't find DLL entry point BCryptHash in bcrypt.dll

J.A. Coutts

Note: Because I don't have VB6 on a Win 10 machine, this program has never been run in the IDE, only as an executable on Win 10.
Attached Files

CheckBoxCombo 1.3 (A professional, effective and ready-to-use Multi-select ComboBox)

$
0
0
What is CheckBoxCombo?

CheckBoxCombo is a general-purpose Multi-select ComboBox User Control designed for Visual Basic. It differs from the conventional ComboBox behavior by allowing user to select one or more items from its drop-down list. CheckBoxCombo greately integrates the existing power of standard VB controls (ComboBox and ListBox) to provide its powerful features and can be easily integrated into any sort of Windows GUI project in VB. Sure, it's a must to have companion in your standard VB Toolbox.

Why is CheckBoxCombo?

The conventional ComboBox control in VB allows you to select only one item at a time from its drop-down list. It cannot be used in situations where you need to select more than one item at a time. For this particular purpose you should use a multi-choice enabled ListBox, which is all right, if you have enough space on your interface/form. But what if you have a very limited space to place the ListBox with dozens of items; may be closer to the bottom of your interface? CheckBoxCombo is a great replacement in such situations where you need to save the space on your UI (User Interface), with its great dynamic features.

CheckBoxCombo is also elegant in providing multiple inputs to SQL queries in database programming.

Further, CheckBoxCombo allows you to set any of its properties even at run-time, which is not even allowed by the traditional ComboBox control. One such property is [sorted], which you can dynamically set the sorting at run-time. This gives you a great flexibility in using the user control simply by overriding the design-time settings as you wish. CheckBoxCombo also exposes some methods to support less coding when working with it.

Its [OnListSearch] property helps user to search and select any item in the list easily.

The user control greatly supports for modern visual styles since it integrates the existing VB controls which support visual styles.

The ActiveX version of CheckBoxCombo is fully compatible even with VBA, if you need to use CheckBoxCombo with Microsoft Office (32-bit) as well.

With CheckBoxCombo's professional features and familiarity in use due to nearly familiar syntax it provides, you will more feel it like a must to have control in your standard VB Toolbox.

Outstanding features of CheckBoxCombo:

  • Professional, effective and ready-to-use design for any sort of Windows GUI project in VB
  • No dependent modules, extremely easy to integrate as a single module
  • Extremely easy to use
  • Ability to setup all supported properties even at run-time
  • Very smooth and faster operation, even with thousands of items
  • Dynamic sorting on ascending or descending, supporting thousands of items
  • Supports for different longest-text-display modes
  • Search-and-select feature for items
  • Exposes methods to support less coding
  • Highly flexible and configurable
  • Powerful and reliable on all supported operations
  • User friendly and familiar syntax
  • Supports for all flavors of Windows from Windows XP with visual styles
  • Full ActiveX compatibility with VBA (Microsoft Office 32-bit)
  • And more...

Note: Please go through the User Documentation and study the Demo Application attached herewith, so that you may get a clear idea about CheckBoxCombo.

Comments, suggestions are greatly welcome...

Version History:
Code:


Revision update 1.3.3 (23-07-2018)
 ----------------------------------
 • Fixed a minor bug when displaying the drop-down list
  (Translucent rectangle appearance issue on the screen
  due to some visual-effect settings of the OS)
 
 Revision update 1.3.2 (18-07-2018)
 ----------------------------------
 • Made internal improvements in hooking machanism
 • Bugfixes in ActiveX
 
 CheckBoxCombo 1.3 (15-07-2018)
 ------------------------------
 • Made changes to ActiveX version to be fully compatible with VBA.
  Now it’s possible to use CheckBoxCombo even in UserForms,
  Spreadsheets, Documents, etc. in Microsoft Office 32-bit editions
 • Optimized hooking mechanism
 • Fixed issues with MDI
 • Fixed issues related to Display Monitor
 • Fixed issues with mouse-wheel and scrollbars
 • Made minor changes to documentation

 CheckBoxCombo 1.2 (05-07-2018)
 ------------------------------
 • Included FillList method. Now the list can be filled by
  a String/Variant type array
 • Fixed the scrollbar issue
 • Enhanced the mouse-click support for selecting/unselecting
  items in the list. Now mouse-click supports anywhere on the
  list item for quick selections
 • Fixed several minor bugs and general optimizations were done
 • Updated User Documentation
 
 CheckBoxCombo 1.1 (30-06-2018)
 ------------------------------
 • Made syntax changes of AddItem, RemoveItem and FindItem methods
 • Introduced DelimiterConact Property
 • Introduced CBCUPdate Property
 • Introduced CBCUpdateCompleted event
 • Revised <Change> event in v1.0 to <ItemCheck>
 • Fixed several bugs and some optimizations were done
 • Updated User Documentation

CheckBoxCombo 1.0 (26-06-2018)
 ------------------------------
 • The initial version of CheckBoxCombo

Attached Images
    
Attached Files

Add-In to Replace Fonts

$
0
0
Here's a little Add-In I wrote, primarily for replacing all the MS Sans Serif fonts in large projects I've got, and I thought I'd share. It does allow you to replace any screen-available font with any other screen-available font. It's been something I've wanted/needed to do for some time.

Here's a screenshot:

Name:  ReplaceFont.png
Views: 326
Size:  7.9 KB

Let me give some caveats to start:

  • I haven't tested it for any MDI-type projects, and I'm not sure what it'll do in those situations.
  • I always use my IDE in a SDI mode, but I don't think that should make any difference.
  • I didn't do the work to make an IDE Toolbar button for it. However, once it's loaded, it'll appear as a menu sub-item on the Add-Ins menu. If you click the "Hide Me" button on the interface, just click the "Replace Font" sub-menu item, and it'll re-appear.


Also, let me talk a bit about Add-Ins for the uninitiated. There are a couple of different ways to execute this Add-In: One, you can just load it in the IDE and execute it. When you do this, it'll execute but nothing much will happen. However, if you load a second copy of the IDE and then call up your Add-In Manager, you'll see this Add-In. If you Load it, you'll then see the Add-In. However, all of this is more-or-less a mode for debugging the Add-In.

The second way to use it is to compile it. It'll make an Add-In-type ActiveX DLL. And, the mere act of compiling it will also register it. Just because I'm a nice guy, I've also included two little DLLReg.vbs & DLLUnreg.vbs scripts. If you drag the compiled DLL onto either of those scripts, it'll register/unregister it. If you compiled it, but didn't compile it where you want it to permanently reside, this will allow you a way to move it (unregister, move the DLL, re-register). Personally, I have a VB6_Addins folder in my Microsoft Visual Studio folder, and that's where I keep these DLLs. Also, the act of compiling will create a couple of other files (ReplaceFont.exp & ReplaceFont.lib), but those aren't needed and can be deleted. Just don't delete the source files (ReplaceFont.vbp, ReplaceFont.frm/x, ReplaceFont.Dsr).

Let me say a bit about the features too:

  • If you specify controls (in addition to forms), it will go through all controls of the form, regardless of whether or not they're nested in containers.
  • The "List w Font" button doesn't actually do anything to your project. However, it goes through all the forms and controls, and makes a list of the forms that have the "From" font somewhere on them. It's just a way to get an idea of what the "Do The Font Replacement(s)" button will do if you click it.
  • The "Segoe" and "Microsoft Sans Serif" buttons are just a couple of quick options for filling in the "To" font.


UPDATE (July 1, 2018, version 1.01): Fixed the tab order, alphabetized (sorted) the ComboBoxes, added an option to cover CTL & PAG files in addition to FRM files.

Enjoy,
Elroy
Attached Images
 
Attached Files

Detect DLL support

$
0
0
I found an API call that simplifies the Hash process by combining several steps into one:

http://www.vbforums.com/showthread.p...017-VB6-Hash10

It only works with Win 10, and I was curious if there was a performance advantage. So I hashed a 7,042 KB file several times with the old process, and with the newer process on the same Win 10 machine. The average time taken with the old process was 0.101 seconds, compared to 0.065 seconds with the newer process. I cannot explain why, but there does seem to be an advantage to using the newer process when it is available. That would mean being able to detect if the newer call was supported. So I came up with this:
Code:

    On Error Resume Next
    'Test if Win 10 API supported using dummy call
    Call BCryptHash(0&, 0&, 0&, 0&, 0&, 0&, 0&)
    If Err = 453 Then 'Use original API cslls
        bHash = HashData(StrPtr(HashAlg), bBuffer)
    Else 'Use Win 10 Calls
        bHash = Hash10Data(StrPtr(HashAlg), bBuffer)
    End If

Is there a better way to accomplish this?

J.A. Coutts

VB6 Simple Virtual ComboBox (OwnerDrawn)

$
0
0
As the title says, a simple approach to accomplish ownerdrawing from Data in external Data-Containers
in a "DropDown-scenario".

As usual with virtual (bound) Controls, they are internally lightweight, since the Drawing happens on the outside.

Nevertheless (depending on what the OwnerDraw-Event offers), a typical scenario
can usually be implemented in only a few lines of OwnerDraw-Handler-Code -
right on the Data of your exernal DataSource-Container (be that an Array, a Collection or a Recordset).

The implementation below is based on only about 140 Lines of UserControl-Code.
Feel free to swap the SubClasser (Tricks clsSubClass currently) to your own implementation, if you like...

And since "Multi-Select-DropDown-scenarios" are apparently "en vouge" these days,
the Control supports this as well - as the ScreenShot below shows:


Ok, here's the Demo-Code: VirtualCombo.zip

Have fun with it...

Edit: enhancement of the MinVisibleItems-Prop, to work also in non-manifested environments.
Edit2: MouseWheel-based Scrolling now updates the currently selected Item-under the Mouse + additional Event (MouseMoveOnItem, to address Hover-Areas within a given Item)

Olaf
Attached Files

(VB6) Err.Raise using HRESULT_FROM_WIN32 and vbObjectError

$
0
0
Convert Win32 error using vbObjectError and HRESULT_FROM_WIN32

HRESULT_FROM_WIN32 is the name of a macro used in C to convert a WIN32 error into an HRESULT error (although since XP it has been replaced by an inline function).

The Win32 errors are easily converted into HRESULT errors. Win32 errors are 16 bit values, whilst HRESULT errors are 32 bit values. The additional 16 bits define the Facility and the Severity of the error. HRESULT encapsulates Win32 errors when the Facility code is set to FACILITYT_WIN32 and severity set to SEVERITY_ERROR and the low 16 bits contain the Win32 error number.

vbObjectError is the exact value of an HRESULT with the facility code set to FACILITY_ITF.

Visual Basic will recognize a returning HRESULT from a function and process it automatically using Err.Raise. When you raise an error in Visual Basic with "Err.Raise vbObjectError Or nMyError," you are unknowingly using an HRESULT with a status code of nMyError.

It is a small step to convert from a FACILITY_ITF used in vbObjectError to a FACILITY_WIN32 required to encapsulate Win32 API errors. Win32 errors are then recognised by Visual Basic as an HRESULT and the Err.Description includes the description of the Win32 error.

The conversion is to take the 16 bit Win32 errors and combine this with FACILITY_WIN32 and SEVERITY_ERROR. It is not necessary to use the vbObjectError but because of the HRESULT connection, it illustrates how Visual Basic can use HRESULT errors.

The constant vbObjectError is derived from the FACILITY_ITF code together with the Error severity code.
vbObjectError = FACILITY_ITF or Severity_Error
= (4 << 16) or 0x80000000


This vbObjectError can be used to create a new constant vbWin32Error by adding an adjustment for the different FACILITY codes FACILITY_ITF and FACILITYT_WIN32.
vbWin32Error = vbObjectError + ((FACILITY_WIN32 - FACILITY_ITF) * (2 ^ 16))

The Win32API error can then be converted to an HRESULT error by adding this constant vbWin32Error to the error, and the error can be trapped using the Visual Basic Err.Raise method, and the error description can be accessed using Err.Description.

The resulting Err.Description identifies the error as a Win32 HRESULT by starting the error description with "Automation error"

The function below HRESULT_FROM_WIN32 converts a Win32 Error into an HRESULT, and the function WIN32_FROM_HRESULT converts HRESULT error back into Win32 Error.

Code:

Private Const FACILITY_ITF = 4
Private Const FACILITY_WIN32 = 7
Private Const vbWin32Error = vbObjectError + ((FACILITY_WIN32 - FACILITY_ITF) * (2 ^ 16))

Public Function HRESULT_FROM_WIN32(LastDllError As Long) As Long
    If (((LastDllError And (Not &HFFFF&)) = 0) and (LastDllError <>0)) Then
        HRESULT_FROM_WIN32 = (LastDllError Or vbWin32Error)
    Else
        HRESULT_FROM_WIN32 = LastDllError
    End If
End Function

Public Function WIN32_FROM_HRESULT(HRESULT As Long) As Long
    If ((HRESULT And (Not &HFFFF&)) = vbWin32Error) Then
        WIN32_FROM_HRESULT = (HRESULT And &HFFFF&)
    Else
        WIN32_FROM_HRESULT = HRESULT
    End If
End Function

These functions can be used to raise a VB error from a Win32 api function, using the err.raise method:

Code:

Private Sub UsageExample()
Dim RetApi As Long
    On Error GoTo EH
'    RetApi = Win32ApiFunction() ' returns 0 if error, <> 0 if successful
    If RetApi = 0 Then
        Err.Raise HRESULT_FROM_WIN32(Err.LastDllError)
    End If
    Exit Sub
EH:
    MsgBox "Error Nos : " & WIN32_FROM_HRESULT(Err.Number) _
    & vbCrLf & "Error : " & Err.Description
End Sub


References
  • Q189134 HOWTO: Raise an Error in Visual Basic From Your C DLL
  • MSDN OldNewThing blog - How do I convert an HRESULT to a Win32 error code
  • WinError.h
  • Platform SDK: COM - Using Macros for Error Handling
  • MSDN blog - The evolution of HRESULT_FROM_WIN32


Update July 6th 2018

Google Cloud Natural Language Text-To-Speech

$
0
0
PLEASE SEE THE INCLUDED READ ME FILE FOR COMPLETE INSTRUCTIONS BEFORE RUNNING THE PROJECT

Here is a project I did that shows you how to use the power of Google Cloud for next level natural sounding Text-To-Speech (TTS).
It shows you how to use either Windows Media Player or the Common Controls MultiMedia control to play the audio files.
Google Cloud TTS Documentation

Unfortunately, you can NOT just open the project and run it... It requires you to have a google cloud account with text to speech API enabled. It is complicated to set up but once you do its trivial to use. It is completely free to sign up but does require a credit/debit card. It is completely free for the first 1-4 million characters.They don't charge your account but access will be denied once the limit is reached till you upgrade your account.

Normally you would have a server (called the backend) that processes the request for you in client applications as not to leak your access tokens.Google cloud tts is free for 1 million characters and after they charge $4 per milllion. I plan on using this in future applications so i couldn't include the access tokens in the code. YOU MUST HAVE YOUR OWN GOOGLE CLOUD ACCOUNT TO RUN THE PROGRAM!
(Note: If someone would like to donate their first 1 million free characters for this example let me know.)

PLEASE SEE THE INCLUDED READ ME FILE FOR COMPLETE INSTRUCTIONS BEFORE RUNNING THE PROJECT

This sample app uses and requires the following technologies:
1. Inet transfer control (MSINET.OCX)
2. Windows Media Player Control (wmp.dll)
3. Common Controls 6.0 (mscomctl.ocx)
4. Common controls multimedia control (mci32.ocx)
5. Google Cloud SDK (see readme file)

It also uses code from the following sources:
1. JSONBAG by Robert D. Riemersma, Jr. (dilettante)
2. GetCommandOutPut by Mattias Sjögren

Name:  ss.jpg
Views: 250
Size:  57.4 KB


GoogleCloudTTS.zip
Attached Images
 
Attached Files

Getting the selected text in the code window (with an add-in)

$
0
0
I have lots of Doc IDs as comments in my vb project eg
Code:

'see doc#25 for more info
And i wanted to be able to quickly show the document.

This code below will show you the selected text and then you can parse it out and respond to any number of things you might find


  1. Create a new project
  2. Select "AddIn" from list of project types
  3. Add a timer to the form frmAddIn
  4. set the timer interval to 300
  5. Add this code to timer1_timer() event


Code:

   
    Dim startLine As Long, startCol As Long
    Dim endLine As Long, endCol As Long
    Dim sContent As String, tmp As String, l As Long
   
    On Error Resume Next
    VBInstance.ActiveCodePane.GetSelection startLine, startCol, endLine, endCol
    On Error GoTo 0

    If startLine <> 0 Then
        For l = startLine To endLine
            tmp = VBInstance.ActiveCodePane.CodeModule.Lines(l, 1)
            If l = endLine Then tmp = Left(tmp, endCol - 1)
            If l = startLine Then tmp = Right(tmp, (Len(tmp) - startCol) + 1)
            sContent = sContent & IIf(Len(sContent) > 0, Chr(10), "") & _
                      tmp
        Next l
    End If
    Debug.Print sContent & "    " & Timer

  1. Run the addIn project
  2. Open or Start another project "Standard Exe"
  3. Click the "add-ins" menu
  4. Click the "My AddIn" sub menu
  5. Open a code window and highlight some code and you will see the highlighted text in the immediate window of the AddIn project


note: I'm also looking for a way to detect what text is under the cursor when hovering over some code. If anyone knows of a way to do this, let me know.

VB6 - Transit Time Tester V2

$
0
0
Attached is an upgraded version of Transit Time Tester utilizing a subset of SimpleSock.

Users sometimes want to know how accessible a certain site is and how long it takes to get to it. The "ping" command has traditionally been used for that, but there are problems using this utility. The difficulty is created by the way that some routers handle Internet Control Message Protocol (ICMP) packets. These routers give ICMP packets the lowest priority, so the round trip time displayed is highly questionable.

The TTL in "ping" packets does not actually represent a "Time To Live". It is a hop counter. To prevent a packet from going into an endless loop, the TTL is decremented as it goes through each router. If the counter gets to zero, the router is supposed to send a message back to the originator. "Tracert" utilizes this feature. The TTL is incremented for each ping packet that it sends out, so in theory it can track the packet as it goes through each router. Some routers have the feature turned off to prevent "Ping Floods" or if they are deemed too busy to handle them.

One would expect that the return time would increase as the TTL is incremented. But that is often not the case, due to the fact that routers give these packets a lower priority and delay them.

"Ping", (as well as "Tracert") utilize UDP packets, which do not establish a connection with the far end. Transit Time Tester uses TCP packets, which are initiated using a 3-way handshake. The client sends a SYN request, the server responds with a SYN-ACK, and the client completes the connection with an ACK. Transit Time Tester measures the time required to receive the SYN-ACK, and prevents the connection from being established by forcing an error.

When it came time to write this description, the network was not that busy and the return times pretty well matched the ping times. Fortunately I had some historical data that represented the case.

Using the "Ping command:
C:\>ping 96.53.96.50
Pinging 96.53.96.50 with 32 bytes of data:
Reply from 96.53.96.50: bytes=32 time=52ms TTL=58
Reply from 96.53.96.50: bytes=32 time=50ms TTL=58
Reply from 96.53.96.50: bytes=32 time=52ms TTL=58
Reply from 96.53.96.50: bytes=32 time=49ms TTL=58
Ping statistics for 96.53.96.50:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 49ms, Maximum = 52ms, Average = 50ms

Using "Transit Time Tester" as shown below yielded an average time of 47 ms. The "Ping" was returned by the router in front of the server (one less hop), and clearly demonstrates that the TCP packets had a higher priority.

For the domain, you can use the domain name, the domain IP Address, or just copy and paste the URL. If the URL is used, the port is automatically adjusted to 80.

J.A. Coutts
Attached Images
 
Attached Files

Comprehensive Shell (CreateProcess & ShellExecuteEx Together)

$
0
0
Module mShellW – Creating New Processes

Overview This module greatly extends what you can do with the Shell function in VBA or Visual Basic 5 or 6 (VB6):
  • Everything is Unicode, including the Shelled-to environment.
  • The code works “as-is” in 32 or 64-bit MS Office or in Visual Basic 5 or 6.
  • This module can be run on Windows XP and later.
  • You can start a program by specifying a document with an extension. For example, if you specify D:\MyFiles\abc.docx and MS Word is registered to open .docx files then Word will start with this file.
  • There is a very easy function to use to shell to CMD.EXE that takes care of all of the intricacies in setting up the commandline to CMD.
  • You can specify how long, if at all, the code waits for the shelled-to program to complete before returning. Specify anything from 0 to effectively forever. You can also specify a time for a pop-up window to the user if he wants the program to quit waiting any further. This is a nice escape from a program that you specify “wait for forever to return” and it gets hung up and never quits.
  • You can execute programs from anywhere on your PC. For example, if you are running 32-bit VBA or VB6 but are running on a 64-bit version of Windows, you stil can run any 64-bit program. You can even tell it that you want to run the 64-bit version of calc.exe and many other programs that reside in the Windows\System32 folder. Normally a 32-bit program gets redirected away from this folder “behind the scenes” but we work around that problem.
  • You can run programs that require elevated permissions (the UAC prompt). Normally this is not possible because the Windows CreateProcess function won’t do this but you have the option to 1) keep the privilege level the same as it currenty is, 2) run the new process elevated, 2) run the new process elevated only if it is required (avoids the UAC prompt unless it is necessary) or 3) do not run elevated (fails if elevation is required).
  • If your program is running elevated, you can specify that the shelled-to routine is non-elevated. Usually a shelled-to routine will be elevated if the host program is elevated.
  • You can run batch files (.bat and .cmd), windows scripts and PowerShell all without knowing anything other than the extension of the file to “run.”
  • You can execute a program if you don’t know where it is. For example, you installed Notepad++.exe in “C:\Program Files (x86)\” but as the programmer you don’t know if your users installed it there or if they even installed it at all. And to make matters worse, if they did install it, did they install the 32 or 64-bit version? This code can find the executable file.
  • Normally, shelling is done via the CreateProcess Windows API call, the significance of which is that the new process is independent from the calling program which makes it multi-threaded. You can have the calling program wait until the shell-to routine is complete or you can return control to the calling program and have it continue while the shelled-to program runs in the background. The other common method of shelling to an external program is to use ShellExecuteEx but that routine has limitations which we avoid with CreateProcess. ShellExecuteEx’s main advantage is being able to specify a document instead of an executable and we provide that functionality without using ShellExecuteEx. However, we do include ShellExecuteEx so you can specify it if you really want. Also, ShellExecuteEx is the routine we use to raise permissions when desired or required since CreateProcess lacks that capability.
  • You can use the Windows’ CreateProcess function or ShellExecuteEx functions for your external call. There are pros and cons for each approach; either will work in most instances. The differences are discussed later in this document. CreateProcess is not limited to 255 characters in the commandline. ShellExecuteEx can run programs with elevated privileges.
  • Most programs start a new instance of themselves when we open with CreateProcess even if an existing instance is running. However, this is not true by default for MS Excel, MS Word and Notepad++. If an instance is already running when you specify opening another one, the new document(s) will eb opened in the instance that is already running. This may be okay but know that the new documents share the same memory (if you are running 32-bit versions of these programs this could be limit) and if for some reason something causes the instance to crash then everything in it including the new documents will crash as well. If they are in a different instance they have their own memory space and do not normally crash when another instance crashes. When you use DocShellW in this module you can specify that the shell is to a new instance and if the program is MS Excel, MS Word or Notepad++ then we apply some special code to force them to start a new instance. You can keep the other behavior of putting them al into one instance by specifying NewInstance as False in the call.
  • This module requires the use of my core library mUCCore. It provides my error handling ystem, Unicode support, the basis for support for all flavors of VBA including 64-bit as well as VB6 (compiled or in the IDE) and it contains many routines I use all of the time. It is accompanied by a separate user guide. You don’t need to know what it does in order to use this shelling module but you may find many parts of it useful for your programs.
  • When I test my shell functions I can hard-code various files I want to open or programs to run. I can’t do that with the sample program I have provided because your files are different than mine and are in different locations than mine. So I have included another of my library modules, this one named FileStuffLite. It includes many things not needed for mShellW but I am using a small part of it just for the demo/test. It is not needed for mShellW to function.
  • The code is LARGEADDRESSAWARE. For VB6 runing in 32-bit Windows you can access up to 3 GB of memory and if run in 64-bit Windows (yes, VB6 itself is 32-bit) you can access up to 4 GB. If you are running Excel 2013 or 2016 you can acces up to 4 GB of memory. This shell by itself does not set that up but it is coded such that you won’t get memory crashes from this module when data or code is above the 2 GB mark.

Main Routines ShellW – The main routine for running another program. DocShellW – Open a file with whatever program is registered in Windows for opening that type of file. For example, you could specify “Test.doc” and the file would be opened with Microsoft Word on most PC’s but if .doc files are set to be opened with some other program then that one is used. CMDRun – Run a batch file, a PowerShell file, a program, a document file or just a command prompt via CMD (very similar to the old DOS prompt). You control whether it goes away after executing whatever you want it to do. Support Routines QuoteIfNec – If the specified string (normally a path to a program or a document) has a space character in it Windows generally wants it enclosed in quotes. This routine checks if the string has a space character and if so it encloses the whole string in quotes. ShellHandlesClose – Closes process and thread handles and resets internal variables for them to 0. HasProcessClosed – Determines if a specified process has ended. IsExeRunning – Returns True if the specified EXE file is running. FindEXEPath – Returns the full path of the specified .EXE file. Can be called within ShellW. FindEXEFromDoc – Returns the program in the current PC’s registry that is set to open the specified document file. Can be called from within DocShellW. NOTE - This same package with VBA samples is being uploaded to the Office Development forum here.
Attached Files
Viewing all 1530 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>