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

VB6 - Multiline Textbox Printer

$
0
0
I had previously used a RichTextBox and the SelPrint routine, but I discovered that routine would not work with an InkEdit Control. With the help of jpbro, we put together a routine for the InkEdit Control (located in the parent forum). But that routine does not work with a Textbox, and I could not find anything online to fit the bill. So I came up with the routine attached.

This routine has experienced very little testing because my development computer does not currently have access to an actual printer. Bug reports would be appreciated.

J.A. Coutts
Attached Files

VB6 - Text Editor

$
0
0
I found a need for addtional functions that NotePad did not provide, so I came up with my own Text Editor. It has most of the functions of NotePad with a couple of extra ones.
Code:

File                Edit                Format                Search
-New                -Undo                -Word Wrap        -Find
-Open                -Cut                -Sort                -Find Next
-Save                -Copy                -Font
-Save as        -Paste
-Print                -Delete
-Exit                -Replace
                -Select All

The noticeable extra is the Sort function, which is covered in a previous post. The other extra is the ability to replace character ranges per line in addition to search and replace specific text. This is accomplished by replacing the double characters CrLf with a single character Cr, using a Split function to separate individual lines into a string array, looping through each line to replace the selected character range, and reassembling the complete string with the Join function. For large text files, search and Replace All by text will be slow, whereas Replace All by character count will be fast by comparison.

The print function has taken some time to put together, as printing from a Text Box is not straight forward, and it has experienced limited testing due to lack of an available printer. It also has been covered in a previous post.

The Line/Col function that comes with Text Editor is not considered an option, as in NotePad. Unlike NotePad, it is available in either Wrap or Unwrap modes, and is only activated by mouse click. If it is important to you, you are welcome to add activation by cursor keys.

Originally I used the API to perform the Edit functions since the VB functions were limited to 64K. But then I discovered that the keyboard functions are not limited to 64K, and perform most of those tasks quite well and with good speed. So it made a lot of sense to use the keyboard functions instead.

Like NotePad, Text Editor provides an adjustable window that remembers it's location and size.

The surprising part of this effort is that with the additional functionality provided, the executable is 1/3 the size of Notepad. I have added functions that meet my current needs, and other users may have specific functions that can be added to meet their needs.

J.A. Coutts
Attached Images
  
Attached Files

[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: 108
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: 85
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: 154
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: 103
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: 318
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: 242
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.
Viewing all 1530 articles
Browse latest View live


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