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

[VB6] RSA Data Signing via CNG

$
0
0
One of the things we get in post-XP Windows is a new crypto library. This offers a number of small advantages such as being a lttle more "rational" from a usage standpoint (calls are somewhat more symmetric) but also some new crypto features such as longer keysize limits for some existing algorithms, elliptic curve cryptography (ECC), and some other goodies.

So here is a simple class CngRsaSign.cls that makes use of Cryptography API: Next Generation (CNG) for creating RSA key pairs and signing and verifying data blobs.

No formal "certificates" are required or used here.


Scope

I won't go into other issues here such as encrypting the data to be signed, or deriving and verifying "Machine ID" fingerprint values. Those have been covered elsewhere and people have lots of ideas about what makes a good machne ID.

I also haven't addressed things like what your Purchase Server and Product Registration Server might do. At a minimum a Purchase process might accept identifying info and payment and return a Product Key of some type. Then within your program or its installer you might have a Registration process that sends back the entered Product Key, some sort of Machine ID, etc. to your Registration Server which returns the signed license data file which your program records to disk.

However here the issue at hand is simply how to sign a blob of data (for example a software license file) so that your applications can validate it against tampering before trusting the values it contains.

Of course this could also be used to sign "messages" you send to people, with the signature being used to prove the message was from you and not tamepred with.


Requirements

Windows Vista or later. There is no redist version of the bcrypt.dll or its dependencies that can be deployed to a Windows XP or older system.

The VB6 development tools of course.


Simple Demo

The demo here just stores two values (Name and Email) in the data blob. These are just stored as "key=value" lines delimited by CRLF in UTF-16LE ("Unicode") text.

You could use UTF-8. You could use XML or JSON. You could use PropertyBag.Contents format. You could encrypt or obfuscate the blob.

Here we do none of that, we just sign it.


Caution

I am not a crypto expert so you will want to verify that nothing being done here weakens the potential advantages of signing such files.


Two Parts

The attachment contains the two-part demo.

The first is Sign.vbp, a simple VB6 program that can (1.) create a key pair which it writes to disk as two blob files, (2.) import the created Private key blob for use in signing data, and (3.) accept Name and Email and then compose the data blob, sign it, and write it to disk.

The second is Verify.vbp, a simple dummy VB6 application. This is even more trivial, and all it does is read the signed data from disk, verify the signature using the Public key blob, and then extract and display Name and Email.


Name:  sshot1.png
Views: 26
Size:  11.2 KB

We have created a key pair, now import the private key


Name:  sshot2.png
Views: 25
Size:  11.2 KB

We have entered the data, now we can create the signed file


Note that the dummy application has a copy of the Public key stored as a custom resource. After you have generated a new key pair, you must replace the existing Public key with your new one and recompile. Otherwise the next step will fail.


Name:  sshot3.png
Views: 23
Size:  10.2 KB

Now we've run the dummy application and
the signed data file has passed verification


Enhancements

For a purpose such as a key file you might be more comfortable concealing the payload, so as previously mentioned you might obfuscate or even encrypt it. But the aim here is just to show how to detect and reject a file that has been tampered with.

One thing you might want to do is create a second stripped down version of CngRsaSign.cls for use in applications. Typically you'd only need to be able to import a Public key and then verify the signature within deployed applications. You could also obfuscate the names of things to help throw anyone off who tries to decompile and patch your applications to bypass this check.


To Run The Demo

Download and unzip the attachment.

Open Sign.vbp and run it in the IDE or compile it and run the EXE. Create a new key pair. Import the Private key, enter the two items of data, and create the signed file.

Open Verify.vbp and edit the resource file: delete the existing Public key, create a new custom resource using your new Public key and of course set its ID and TYPE to match those used in the program. Then run it in the IDE or compile it and run the EXE.

That's it.


Updated attachment

Added a 3rd project Tamper.vbp that can be run to read the data field values, let you alter them, and store the signed file back to disk with alterations. If you run this and change anything then the Verify program should fail - even if you just change one letter, add one, or delete one.

Updated again

Removed some redundant definitions.
Attached Images
   
Attached Files

[VB6, Vista+] SplitButtons

$
0
0
Now that more people are moving off Windows XP we can start using more of the new features added to Windows back in 2006.

One of these is a funny control called a "Split Button" which is really a variant form of a Win32 Button control such as the ones that live inside of VB6's intrinsic CommandButton control. However Microsoft hasn't updated VB6 and isn't likely to, so as with so many things we have to take matters into our own hands and dig around under the covers.

SplitButtons.bas is a VB6 static module designed to help implement the additional capability in CommandButtons.


Split Button?

There are problems this might be a good solution for, but probably not as many as you might think upon first look.

A Split Button is a sort of "composite control" like the ComboBox. Here we have a button combined with a dropdown list. When clicked the button acts like a button. When clicked at the right on the "dropdown glyph" (triangle) a list drops down and the user can select a new meaning for the button.

Normally this changes the button Caption to reflect the new meaning, and future clicks should repeat this selected meaning. Making the change from the dropdown list also acts like a click with the new meaning.


Name:  sshot1.png
Views: 33
Size:  14.0 KB

Changing the first button


Name:  sshot2.png
Views: 44
Size:  18.5 KB

A few buttons later, changing the button at the bottom
of the Form, note the overhang


For whatever reason Microsoft did not build the dropdown list into the enhanced Button control. They just provide some plumbing that allows you to tie a popup menu to the control yourself.

This means you could put all sorts of weird stuff into that menu and have selection do all sorts of crazy things. But it is probably going to be far better for your users if you stick to the "prescribed" behavior of Split Button controls.


Requirements

Windows Vista or later. Rumored to also work in XP (SP2? SP3?) but Vista is documented as the minimum.


Programming Requirements

This will not do anything at all for you unless your program has an application manifest that selects the Common Controls 6.0 assembly.

And when you do that you really want to use a Sub Main() as your "startup object" that loads a couple of libraries in the correct sequence (see the demo). If you fail to do this your programs might work sometimes and then mysteriously crash other times. I don't know why this isn't consistent, but it does lead to some quirky programs floating around out there. Better to just do the load sequencing and be safe.

See the comments in the demo code. They help explain some extra steps required to use Split Buttons in a UserControl too.


IDE Testing

To have the style change make any sense for testing VB6.EXE will need an application manifest.

I don't normally like to work this way because it can mess up a few things, for example some of the "list" properties of control in the Properties Pane of the IDE.

Manifest caching can also make it annoying to try to use file manifests: a change may not show until next reboot. I've had better luck embedding a manifest in VB6.EXE, but I have a nice tool for this. Your mileage may vary.


Testing the Demo

Assuming you have VB6 installed on Vista or later you can just unzip the archive, open the .VBP file, and compile the program without trying to run it within the IDE. Then exit the IDE and run the compiled EXE.


Some Remarks

While a lot of people forget (never knew?) this, the Windows keystroke to "drop" a list (ComboBox, etc.) is the F4 key. From there the user can up/down arrow to choose a list item and Enter to select it. Since Microsoft didn't seem to implement that either, SplitButtons.bas goes ahead and does so. Sadly this makes the code slightly more complex than it might otherwise need to be, and we have to subclass two windows.

Oh well! At least the mouseless will appreciate the effort.

I have noticed that some people implement the dropdown/popup a little differently, indenting the menu to the right 120 to 180 twips or so. Feel free to change this, it should be simple enough.

I think the demo's buttons are a little tall myself, but you can just size those in design mode as with any CommandButton.
Attached Images
  
Attached Files

HTML converter

$
0
0
hello all. I an new to the forum and I have very limited experience in VB. I am looking for the easiest way to convert an HTML table to other formats (csv, etc.) automatically. Any suggestions would be appreciated.

[VB6] RLE8 Compression Algorithm for Bitmaps

$
0
0
Microsoft allows 8-bit bitmaps to be compressed using a somewhat simple, not terribly efficient, run length encoding (RLE). Strict rules apply, but is rather easy to encode/decode
Quote:

Originally Posted by paraphrased from msdn
Encoded runs cannot be larger than 255 bytes
Encoded scanlines terminate with a double null byte (end of line EOL)
Encoded bitmap terminates with bytes: 00 01 (EOF)
Scanlines are Word aligned, not DWord aligned
Associated BITMAPINFOHEADER fields required: biCompression=BI_RLE8: biSizeImage = size of encoded pixels

Encoding: can have several runs per scanline. Each run starts with a control byte:
01-255 indicates a repeated byte run length. The next byte is the repeated byte
00 indicates EOL, EOF or uncompressed run follows. Next byte determines meaning
00 = EOL
01 = EOF
02 = Delta followed by 2 byte "jump-to" coordinates. Not used in this project
03-255 = uncompressed run length & the uncompressed bytes follow
for odd length runs vs. even length, one padding byte is required at end of encoded run

Compression net gain(+)/loss(-) per run:
repeated byte runs: (length of run) - 2
uncompressed runs: if run is even number of bytes: net loss of 2 else net loss of 3
each scanline removes 2 bytes (EOL marker) from any net gain
loss of 2 bytes (EOF marker) from total net gain after all pixels encoded

Whether you are aware of it or not, you can actually get the API GetDibits to compress these 8-bit bitmaps for you. Niffty, fast, but unfortunately, what is returned can actually be larger than the original uncompressed image at times. In any case, I think we can do a bit better than Windows in this area.

Attached is a sample project wrapped around the key routine: pvCompressRLE8. Also included are 2 simple bitmaps to play with. Now trying to go out and find 8-bit bitmaps can be a bit painful, pun intended ;)
Suggestion: for playing around, use Microsoft Paint. Open image in Paint, save image as 256 color bitmap & don't care if the colors get messed up a bit. It's just for playing anyway

The routine I've written is not guaranteed to compress smaller than the total uncompressed size. But it should 99.9% of the time. In fact, it out-performs GetDibits every time (so far). I'm sure there are a few bitmaps that Windows can compress better via GetDibits.

This routine was created simply because I was inquisitive, wanted to see if I could possibly do it better (given how poorly Windows seems to do it). If there are better routines out there, please link them. Think many would like to learn from those also, me included.

Last but not least, I'm not touting this as the best RLE8 routine for VB6ers. But it ain't bad for a 1st attempt. The one I've included could use a little tune-up also.

Edited: Senior moment. Didn't include a browser class in the zip. It's there now.

FYI: If you want to see how Windows does when the routine fails to compress a bitmap, rem-out the "GoTo ExitRoutine" line after the msgbox displaying the failure

Best case scenario for failure and the "compressed" data being larger than the original data size would be a size equal to that shown below (assuming width < 256 else worse results). This is because if no bytes repeated on any scanline, the scanline would be coded with a 2 byte prefix + the entire scanline bytes + 2 byte scanline terminator. The encoding also requires a 2 byte EOF maker. But when compressing fails, the routine aborts so user can write bitmap in original bytes vs writing an even larger bitmap. Note: standard bitmaps without any compression algo applied have their pixels DWord aligned. This means for an 8-bit bitmap, a maximum of 3 padding bytes per scanline can be used for standard bitmaps. Even if that is the case, the minimum extra bytes used in RLE8 compression would be 4 per scanline. In other words, RLE8 without being able to compress any bytes, would be a larger file than not using RLE8 at all:
Code:

<best-case "compressed" size when bitmap cannot be compressed (not good)>
even-value image width: ImageHeight * 4 + 2 + (ImageHeight * ImageWidth)
odd-value image width: ImageHeight * 5 + 2  + (ImageHeight * ImageWidth)
^^ extra padding byte needed per scanline

Attached Images
 
Attached Files

[VB6, Vista+] Query Windows Search

$
0
0
Now that Windows XP is dead we can feel free to make wider use of new features of Windows introduced nearly 8 years ago. One of these that I see almost no use of by VB6 programmers is the ability to query the indexes maintained by Windows Search. Sad, because it is really pretty easy.

I think the easiest way to make use of Windows Search programmatically is to use its SQL syntax via ADO and the data source object provided as part of Windows Search in Windows Vista and later. This was even made available for Windows XP SP2 if you had installed Windows Desktop Search 3.x, which might still be available to download for a few months yet.

This can be used to do simple or complex searches of disk files, Outlook email, and offline files. You can search on a number of properties and even do full-text searching of file types that have an appropriate filter installed.


Here are a few links to articles, mostly old now and mostly .Net oriented:

Searching the Desktop

An Introduction to Vista's Integrated Search Capabilities


There is also the MSDN topic:

Windows Search

Jumping deeper within that section we find:

Querying the Index with Windows Search SQL Syntax


Of course to be of value the data you want to query on needs to be in an indexed location. For example Program Files normally isn't indexed, while the Users area generally is. Indexed locations are determined administratively via the Indexing Options, which you can find in the Control Panel.


Name:  sshot0.jpg
Views: 4
Size:  15.1 KB

Indexing Options


The sample code in the attached demo is an example of some basic use of Windows Search queries. Here you can specify a target folder (or none, meaning all indexed locations on all drives) and an optional list of file names to look for, as well as a limit for the number of hits to report:


Name:  sshot1.jpg
Views: 7
Size:  15.5 KB

Find all "readme.txt" in "d:\Downloads"


When the results are returned the demo lists out the requested property values in a flexgrid:


Name:  sshot2.jpg
Views: 5
Size:  49.0 KB

24 hits


In addition to the documentation on MSDN, I find the propkey.h header file from the Vista SDK quite helpful. The Windows 7 SDK should have a newer version of the same file.
Attached Images
   
Attached Files

[VB6] RLE8 Compression Algorithm for Bitmaps (Updated)

$
0
0
Updated. Added a few tweaks to the code to squeeze a few more bytes of compression. In some cases, it is significant, but on average, reduction of a couple hundred bytes achieved. See Post #2 for which ones I included & which still may be doable. Also updated the zip to include 2 more bitmaps: 1) one that this project & Windows can't compress smaller & 2) one where Windows can't compress, but this project compresses pretty well

Microsoft allows 8-bit bitmaps to be compressed using a somewhat simple, not terribly efficient, run length encoding (RLE). Strict rules apply, but is rather easy to encode/decode
Quote:

Originally Posted by paraphrased from msdn
Encoded runs cannot be larger than 255 bytes
Encoded scanlines terminate with a double null byte (end of line EOL)
Encoded bitmap terminates with bytes: 00 01 (EOF)
Scanlines are Word aligned, not DWord aligned
Associated BITMAPINFOHEADER fields required: biCompression=BI_RLE8: biSizeImage = size of encoded pixels

Encoding: can have several runs per scanline. Each run starts with a control byte:
01-255 indicates a repeated byte run length. The next byte is the repeated byte
00 indicates EOL, EOF or uncompressed run follows. Next byte determines meaning
00 = EOL
01 = EOF
02 = Delta followed by 2 byte "jump-to" coordinates. Not used in this project
03-255 = uncompressed run length & the uncompressed bytes follow
for odd length runs vs. even length, one padding byte is required at end of encoded run

Compression net gain(+)/loss(-) per run:
repeated byte runs: (length of run) - 2
uncompressed runs: if run is even number of bytes: net loss of 2 else net loss of 3
each scanline removes 2 bytes (EOL marker) from any net gain
loss of 2 bytes (EOF marker) from total net gain after all pixels encoded

Whether you are aware of it or not, you can actually get the API GetDibits to compress these 8-bit bitmaps for you. Niffty, fast, but unfortunately, what is returned can actually be larger than the original uncompressed image at times. In any case, I think we can do a bit better than Windows in this area.

Attached is a sample project wrapped around the key routine: pvCompressRLE8. Also included are 2 simple bitmaps to play with. Now trying to go out and find 8-bit bitmaps can be a bit painful, pun intended ;)
Suggestion: for playing around, use Microsoft Paint. Open image in Paint, save image as 256 color bitmap & don't care if the colors get messed up a bit. It's just for playing anyway

The routine I've written is not guaranteed to compress smaller than the total uncompressed size. But it should 99.9% of the time. In fact, it out-performs GetDibits every time (so far). I'm sure there are a few bitmaps that Windows can compress better via GetDibits.

This routine was created simply because I was inquisitive, wanted to see if I could possibly do it better (given how poorly Windows seems to do it). If there are better routines out there, please link them. Think many would like to learn from those also, me included.

Last but not least, I'm not touting this as the best RLE8 routine for VB6ers. But it ain't bad for a 1st attempt. The one I've included could use a little tune-up also. See post #2

Edited: Senior moment. Didn't include a browser class in the zip. It's there now.

FYI: If you want to see how Windows does when the routine fails to compress a bitmap, rem-out the "GoTo ExitRoutine" line after the msgbox displaying the failure

Best case scenario for failure and the "compressed" data being larger than the original data size would be a size equal to that shown below (assuming width < 256 else worse results). This is because if no bytes repeated on any scanline, the scanline would be coded with a 2 byte prefix + the entire scanline bytes + 2 byte scanline terminator. The encoding also requires a 2 byte EOF maker. But when compressing fails, the routine aborts so user can write bitmap in original bytes vs writing an even larger bitmap. Note: standard bitmaps without any compression algo applied have their pixels DWord aligned. This means for an 8-bit bitmap, a maximum of 3 padding bytes per scanline can be used for standard bitmaps. Even if that is the case, the minimum extra bytes used in RLE8 compression would be 4 per scanline. In other words, RLE8 without being able to compress any bytes, would be a larger file than not using RLE8 at all:
Code:

<best-case "compressed" size when bitmap cannot be compressed (not good)>
even-value image width: ImageHeight * 4 + 2 + (ImageHeight * ImageWidth)
odd-value image width: ImageHeight * 5 + 2  + (ImageHeight * ImageWidth)
^^ extra padding byte needed per scanline

Attached Files

[VB6, Vista+] Simple Task Dialog

$
0
0
I posted sample code using this class for raising simple Task Dialogs several times over the years, but I never gave it a CodeBank thread of its own.


Task Dialogs

Now that Windows XP is dead we can start making more use of features like this to avoid that old Windows 3.1/95 look and feel. This class is a basic wrapper for the calls required to make use of the Task Dialog.

You can expand upon this with callbacks to make use of even more Task Dialog features, but here we have the core subset covered without extra modules to host those callbacks. The result is a simple alternative to the VB6 MsgBox.


Requirements

Window Vista or later.

An application manifest selecting the Common Controls 6 assembly.

Startup logic that loads shell32.dll and comctl32.dll before any Forms or other UI elements - and in the correct sequence.


Details

STDlg.cls is a VB_PredeclaredId = True class so you don't have to create additional instances. It wouldn't make sense to have more than one in a program anyway.

It has just one method: TaskDialog(), loosely patterned on MsgBox().


Caution

STDlg.cls is unlikely to work correctly within the IDE if you run VB6.exe with a Common Controls 6 manifest itself. Most people don't do this though.

Normally it checks the loaded comctl32 version to determine whether to try to use Task Dialog or just substitute a MsgBox call instead. You could add a "running in the IDE" test to the code though.


Name:  sshot.png
Views: 46
Size:  16.0 KB
Attached Images
 
Attached Files

Nice Textboxes

$
0
0
Why some functions are so difficult to find. I would like to have some controls without the restrictions for using...this or that themes..manifests or other bad habits..
So i wrote some textboxes. All of them are based in glist (latest edition).
Here I have a TextViewer to display text with line spacing as we wish and wrapping or not. The only limitation is has no drag and drop,and not for this version undo control.. Because is the glist behind this TextViewer can scroll the text holding down the mouse button and doing a move anywhere in the window of the glist

I also have some textboxes with one line only
- a Combobox with auto complete function (shows/hide a listbox of values)
- a Spinner Textbox for a long value. We can alter the value by clicking and writing, by using up down buttons, by using the scroll bar.
- a simple textbox wit centered text that can be edit ...as is, we can use it without edit, just showing text
- a button that can be slide the caption and perform the "click" (by panning right) (2 buttons using here, one to alter the wrapping of the textViewer, and the other to show/hide the paragraphs marks..
- A floating list of values to put in Spinnet TextBbox. We can "call" like a popup menu. See above the spinner textbox, when you right click.

Thats all...
Attached Images
 
Attached Files

[VB6] Color Management with GDI+ (updated 20 Sep 14)

$
0
0
Updates (see post #2 for bug descriptions):
20 Sep 14
:: Added patch for a specific case when GdipBitmapLockBits fails to lock image data
:: Added support for JPGs where GDI+ won't return any ICC information. See posts 9-13
:: Added support for other 8 bpp images. See posts 14-22
10 Sep 14: Added support for ICC profiles embedded into the BMP format
31 Aug 14: Fixed JPG related GDI+ bug

Higher quality images often have a color management profile (ICM/ICC) embedded into their file. These embedded profiles can be retrieved from GDI+ most times. Not many image formats support embedded profiles, but these do per Color.org: png, tif, jpg & gif. Additionally, per Microsoft, bitmaps can support ICC profiles also.

When embedded, the image's creator provided it so that it can be used to reproduce the image on any monitor/printer in the colors that the creator intended. By ignoring the profile, what you get is not what the creator intended. Sometimes it can be radically different. Images without ICC profiles are at the mercy of the rendering application. GDI+ does a fair job without embedded profiles, but its hands are tied when best-guessing how to interpret the colors.

Windows provided color management for quite awhile now, but it is the application's responsibility to apply it. The flat GDI+ API wrapper doesn't support color management directly. But with the use of Windows APIs we can still use GDI+ and apply color management

For a project that doesn't rely on GDI+ for displaying images with embedded ICC profiles, see Tanner's work here. This project is not meant to be competitive with Tanner's hDC-based solution, it is provided as a workaround for those that exclusively use GDI+ for image rendering/processing, no device contexts used in transformations. I started this about 2 years ago & lost interest. Can rest easier now :)

This sample project uses Windows to help transform colors, but the result is maintained and used by GDI+. From the sample screenshot, you can see a radical example along with a real-world example of how color management can improve what is displayed. And this sample project may include the only VB6 code that processes a GIF embedded ICC profile instead of ignoring them. To be fair, embedded GIFs are really hard to find.

To find other images to play with, google for: color profile test

From time to time, will update this as needed

Request. If anyone would like to upload an 8 bit grayscale JPG, TIFF or PNG with the appropriate ICC profile, embedded or not, please do so. I'd like to examine them. Currently, processing 8 bit images other than GIF/BMP is turned off in the code.
Note: 8 bit image processing turned on with the 20 Sep update

Note: The included bitmap sample image will not be read by VB's LoadPicture function. Believe VB does not support any bitmap using version 4 or 5 of the BITMAPINFOHEADER. But such images can be loaded via setting a DIB's pixel data to the pixel data contained in the bitmap file.

How do I load any profile I want and use it in the transformation?
Open the file and read it ito a byte array, then sample code provided. Project will need to be modified to accept a user-provided profile handle to the pvColorManageImage method.
Note: In most recent update, modified function to include an optional FileName parameter
Code:

hProfile = pvCreateProfile(VarPtr(array(0)), UBound(array)+1)
' array can be erased immediately after function returns
' CloseColorProfile must be called on the returned profile handle, when no longer needed

Attached Images
 
Attached Files

[VB6] TaskDialogIndirect Simple Implementation

$
0
0
So I really liked the implementations of TaskDialog that I've seen, and wanted to take it a bit further. TaskDialogIndirect offers a far greater number of options:



This is the first version; a basic implementation of the standard features.

What IS Supported
-Custom Buttons (either CommandLink style or regular style)
-Radio Buttons
-All fields the text fields available
-Verify checkbox
-Hyperlinks (these are launched with ShellExecute)
-Custom icons: see notes at bottom of post

What Is NOT Supported
All of these are in the works for the full implementation.
-Support for ProgressBar
-Autoclose/Timer feedback
-Feedback for user actions in the dialog
-Changing text icons while displayed


The sample project attached calls the dialog shown in the picture above.

The main function is ShowTaskDialogEx:
Code:

Public Function ShowTaskDialogEx(hWnd As Long, _
                                hInstance As Long, _
                                dwFlags As TASKDIALOG_FLAGS, _
                                dwButtons As TDBUTTONS, _
                                sTitle As String, _
                                pszIconMain As TDICONS, _
                                sMainInstr As String, _
                                sContent As String, _
                                cButtons As Long, _
                                uBtns() As TASKDIALOG_BUTTON, _
                                nDefBtn As Long, _
                                cRadButtons As Long, _
                                uRadioBtns() As TASKDIALOG_BUTTON, _
                                nDefRadioBtn As Long, _
                                sVerifyText As String, _
                                sExpandedInfo As String, _
                                sExpandedControlText As String, _
                                sCollapsedControlText As String, _
                                hIconFooter As TDICONS, _
                                sFooter As String, _
                                cxWidth As Long, _
                                out_radio As Long, _
                                out_verify As Long) As TDBUTTONS

hWnd: Parent hWnd; can just be 0& usually.
hInstance: If/when it's required is unclear; so best to just pass App.hInstance to it
dwFlags: See MSDN. All flags can be used, but some would require additional code.
dwButtons: If you're using the standard buttons, set them here using Or to combine multiple buttons. Standard buttons cannot be used by themselves with the CommandLink style.
sTitle: The title of the dialog.
pszIconMain: Specify a value from TDICONS, or an hIcon (see notes)
sMainInstr: Main instruction text
sContent: Text appearing below the main instruction
cButtons: If you're using custom buttons, the number of them, or zero if not used.
uBtns(): The array of custom buttons. Redim(0) and don't set any members if not used, but the empty structure still needs to be passed.
nDefBtn: The button selected by default. Set to the buttons ID, or 0 if unused.
cRadButtons: The number of radio buttons, or 0 if none.
uRadioBtns(): The array of radio buttons. Redim(0) and don't set any members if not used, but the empty structure still needs to be passed.
nDefRadioBtn: The default radio button selected, by ID. 0 if unused.
sVerifyText: The text of the checkbox. If blank, the checkbox is not displayed. Unchecked by default; to make it checked by default use the TDF_VERIFICATION_FLAG_CHECKED flag.
sExpandedInfo: Extra info displayed when the expand button is click. Appears below Content by default; can be made to appear below footer with the TDF_EXPAND_FOOTER_AREA flag, and can be shown by default with the TDF_EXPANDED_BY_DEFAULT flag.
sExpandedControlText: The text for the expand button in its expanded state.
sCollapsedControlText: The text for the expand button in its collapsed state.
hIconFooter: Specify a value from TDICONS, or an hIcon (see notes)
sFooter: The footer text.
cxWidth: Specify a custom width. Set to 0& to have the ideal width determined automatically.

out_radio: Must be passed ByRef; this variable is filled with the ID of the radio button selected (or zero if they're not used).
out_verify: Must be passed ByRef; this variable is 0 if the verification box was unchecked, and 1 if it was checked.

Return value: The ID of the button selected, or 0 if the dialog was cancelled. This will either be a TDICONS value, or the user-supplied ID of the custom button.


Notes:

No subclassing required!

If you don't want to use the radio buttons, the empty structure still needs to be there. Change Redim uRBN(2) to (0), and change cRadButtons to 0.

For custom icons, you must set the TDF_USE_HICON_MAIN flag (and/or TDF_USE_HICON_FOOTER to use one in the footer), then supply an hIcon. Any icon source can be turned into an hIcon, just search for examples. I personally use a method adapted from clsMenuImage. You add the icon to the app's resource file as a custom resource in the VB Resource Editor (NOT as an icon), and then use the technique outlined here. This isn't included in the sample project; it's left to the user to supply the method of getting an hIcon.

As noted above, if you're using TDF_USE_COMMAND_LINKS then you must supply custom buttons. The dialog does not appear at all and the function returns all zeros if you set that flag and don't supply custom buttons. You can, however, use both, by specifying both dwButtons and a uBTN array; but you can't supply custom buttons AND command links.

When using command links, new lines are separated by vbLf alone, instead of vbCrLf. The latter results in the font not being smaller after the first line.

Requirements
TaskDialogIndirect is only supported on Vista and higher.

A CommonControls Manifest is required, both for the compiled project and for VB6.exe to run the code from the IDE, for 6.0 common controls. Like any other such project, it must be started from Sub Main() with an InitCommonControlsEx call.

----------------------------------------------------
In addition to feedback on this, I'd like ideas on how to approach the full implementation. I was thinking of switching over to a class module, that way I could fire events on notifications or the timer, and then update things with property lets. How to approach the progress bar in a way that's useful in general is a particular challenge.
Attached Files

VB6 - Hidden Conversations V3

$
0
0
On the surface, Version 3 looks very much like Versions 1 & 2. Underneath the hood however, cSocket2.cls has been replaced by the slimmer and faster NewSocket.cls, as well as utilizing an updated clsCrypto.cls. Versions 1 & 2 had difficulty working with systems that did not utilize the Latin character set (such as Chinese or Arabic), and the addtion of these 2 classes now makes Hidden Conversations Unicode compatible. It is NOT Unicode compliant.

Like Version 2, Version 3 incorporates a 2048 bit/256 byte Public/Private key pair to initiate the conversation. Using the Public key, the Client sends a random 32 byte encrypted number to the Host. The Host then decrypts that number using the Private key. The Host then sends a Private Key encrypted message to the Client, who decrypts it using the Public key to verify that the Host is the holder of the private key. And you can change that key pair at any time. Of course the Public key has to be sent by alternate means to the Client after a change, as only the Host is capable of creating new keys.

If only one key is present, Hidden Conversations will automatically use that key. However, some Clients will need to converse with more than one Host, and provision has been made to deal with that. In addition to the IP Address and Port, the key file name needs to be stored and recovered. If no Keys are present, the program will complain but will still load. However, without a key you will not be able to communicate.

All this security would be useless if an unauthorized person gains physical access to the resident computer. The password is saved in the registry as a hashed number.

To permit longer packets to be sent, the packets are formatted with a record header that includes the packet length along with version information.

J.A. Coutts
Attached Files

Nice Textboxes version2.1 Plus Varius Selectors

$
0
0
Why some functions are so difficult to find. I would like to have some controls without the restrictions for using...this or that themes..manifests or other bad habits..
So i wrote some textboxes. All of them are based in glist (latest edition).
Here I have a TextViewer to display text with line spacing as we wish and wrapping or not. The only limitation is has no drag and drop,and not for this version undo control.. Because is the glist behind this TextViewer can scroll the text holding down the mouse button and doing a move anywhere in the window of the glist

I also have some textboxes with one line only
- a Combobox with auto complete function (shows/hide a listbox of values)
- a Spinner Textbox for a long value. We can alter the value by clicking and writing, by using up down buttons, by using the scroll bar.
- a simple textbox wit centered text that can be edit ...as is, we can use it without edit, just showing text
- a button that can be slide the caption and perform the "click" (by panning right) (2 buttons using here, one to alter the wrapping of the textViewer, and the other to show/hide the paragraphs marks..
- A floating list of values to put in Spinnet TextBbox. We can "call" like a popup menu. See above the spinner textbox, when you right click.

Version 2
- ComboBox - works fine.
- CheckBox
- Info popup in a textbox demonstration
for document type
- Simple undo (undo for deleted marked text and for paragraph changes), use control Z
- Control A (select all)
- Double click select word
- Drag and Drop
you can move or copy from and to same document. double click a marked text show the drag icon. This is not the same as holding down the mouse and move. This function is for moving like using a stick the scroll bar.

Last Version
This version is almost identical to the one before. When we mark text a up or down movement of caret (or cursor) unmark the text. A second touch is about the showing of scrollbar. It was a small appearance of that scroll bar when showing the form who hold the control, that it isn't pretty, especially for that glists where the items are less or equal of viewing lines. A last touch was for document (textviewer class) for the example with file selector, a missing +1 chenage the line for caret in a drag over event when no header used (drawing) in the glist.

For the Selector Example.
Open Load File Selector and open a txt file (UNICODE or not). A new form opens with one text box (the standard one) and one from textviewer class (a wrapper class for glist4 listbox control). From file menu check enable to write and check the other options to see what happen. Also the textviewer resize as we resize the window, and the wrapping is fast, very fast (enable it from file menu). Also see that classic textbox has flickering. No flickering for Textviewer.

If anyone want the scroll bar only, then that code can be found it in Scrollio example, (I wrote the scroll bar for the scrollio control, as an image/drawing viewer, and then I do a merge of that code to the glist, the one with ...millions of items...that I posted here some months ago).

I have started the major task to, and I have exclude file,folder, color and font selectors from M2000 Environment and Interpreter, and now is time to through the classic textbox.



That's All
...for now

Look #4 for latest versions
Attached Images
 
Attached Files

[VB6] TaskDialogIndirect: Complete class implementation of Vista+ Task Dialogs

$
0
0
cTaskDialog 0.3.3
Say goodbye to unsightly, primitive messageboxes forever!



Download Attachment: cTaskDialog 0.3.3.zip

**If you have 0.3 please replace it. Important bugfixes have been made with dll icons and ReleaseButtonHold**


cTaskDialog is the sequel to my previous TaskDialogIndirect project, mTaskDialog. This version adds support for all TaskDialogIndirect features, including the progress bar, timer feedback, updating the text and icons while the dialog is open, and events for all the notifications. It's also much easier to use.

What is TaskDialog?

TaskDialog, introduced in Windows Vista, is a massive upgrade to the MessageBox. While not as simple, it offers a huge array of features... custom icons, custom button text, command link style buttons, expanded info button, a footer, a checkbox for 'i read this' or 'don't show this again' type messages, radio buttons, hyperlinks, and more.

This project can be used to create a simple messagebox like the older ones, to an extremely complex dialog with all the features mentioned, even all at once!

Before using cTaskDialog

The TaskDialog was introduced with version 6.0 of the common controls, with Windows Vista. That means a manifest is required for your compiled application, and for VB6.exe in order to use it from the IDE. In addition, your project must start from Sub Main() and initialize the common controls before any forms are loaded. The sample project includes Sub Main(), and see LaVolpe's Manifest Creator to create the manifests.

Setting Up cTaskDialog

Your project must include cTaskDialog.cls and mTaskDialogHelper.bas. mTaskDialogSample.bas is only required for the sample project, though if you want to use hyperlinks make sure you keep the ShellExecuteW api and do not use regular ShellExecute common API as it usually points to ShellExecuteA.
Once you've got a project using the modern common controls, cTaskDialog is similar in use to a lot of other class modules, like the other common controls.

To initialize the class, put the following at the start of a form and in the Form_Load code:
Code:

Private WithEvents TaskDialog1 As cTaskDialog

Private Sub Form_Load()
Set TaskDialog1 = New cTaskDialog
End Sub



Now, you're all ready to begin using it. Let's start with a simple messagebox like we've seen before.

Creating this box is very straightforward. Unlike the previous incarnation, you don't have to worry about anything you're not using.

Code:

Private Sub Command2_Click()

With TaskDialog1
    .MainInstruction = "This is a simple dialog."
    .CommonButtons = TDCBF_YES_BUTTON Or TDCBF_NO_BUTTON
    .IconMain = TD_INFORMATION_ICON
    .Title = "cTaskDialog Project"
   
    .ShowDialog

    If .ResultMain = TD_YES Then
        Label1.Caption = "Yes Yes Yes!"
    ElseIf .ResultMain = TD_NO Then
        Label1.Caption = "Nope. No. Non. Nein."
    Else
        Label1.Caption = "Cancelled."
    End If
End With
End Sub

That's all it takes for a basic messagebox. The .Init() call resets the dialog. If you want to re-use all the previous settings and just change a couple things, it can be skipped.
If you put your text in .Content and nothing in .MainInstruction, it will look like the dialog on the bottom.


Now that basic usage is covered, let's get down to what you really came for: advanced features!

Here's a few basic changes that make a much more fancy looking dialog:

Code:

    .Init
    .MainInstruction = "You're about to do something stupid."
    .Content = "Are you absolutely sure you want to continue with this really bad idea?"
    .CommonButtons = TDCBF_YES_BUTTON Or TDCBF_NO_BUTTON
    .IconMain = TD_SHIELD_WARNING_ICON 'TD_INFORMATION_ICON
    .Title = "cTaskDialog Project"
   
    .ShowDialog

The TaskDialog supports several special shield icons that create the colored bar uptop. If you use a regular icon, or a custom icon, it will look like the dialog on the bottom.



All the other text fields are added the same way, so I'm just going to skip over those. One thing to note, with expanded information set, the little expando button appears automatically when you set those fields and requires no additional code to operate; where it appears is set by a flag, which is described later. Also note that the major text fields can be changed while the dialog is open, just set it again the same way.

One of the big features is the ability to customize the text on the buttons. Due to limitations in VB, I've implemented them by using a .AddButton function. You can assign the button the same id as one of the regular buttons, or give it a unique id. Custom buttons can be removed with .ClearCustomButtons so a full Init() call isn't needed.

Code:

With TaskDialog1
    .Init
    .MainInstruction = "You're about to do something stupid."
    .Content = "Are you absolutely sure you want to continue with this really bad idea?"
    .IconMain = TD_INFORMATION_ICON
    .Title = "cTaskDialog Project"
    .AddCustomButton 101, "YeeHaw!"
    .AddCustomButton 102, "NEVER!!!"
    .AddCustomButton 103, "I dunno?"
   
    .ShowDialog

    Label1.Caption = "ID of button clicked: " & .ResultMain
End With

Note that we have removed the .CommonButtons. If you specify buttons there as well, they will appear in addition to your custom buttons.

Radio buttons are added the exact same way as common buttons; and the ID of the radio button selected is found in the .ResultRad property.

Code:

    .AddRadioButton 110, "Let's do item 1"
    .AddRadioButton 111, "Or maybe 2"
    .AddRadioButton 112, "super secret option"
   
    .ShowDialog

    Label1.Caption = "ID of button clicked: " & .ResultMain
    Label2.Caption = "ID of radio button selected: " & .ResultRad


One of the other biggies are Hyperlinks. These require a few additional steps. First, you need to include TDF_ENABLE_HYPERLINKS in the .Flags property. Then, you add in the hyperlink as normal html, but the url needs to be in quotes. Then you'll need to use one of the events for the class. The most common thing to do is just execute the link, so that's what's shown here, but you could also get the URL back from the pointer and do something else with it. You must use ShellExecuteW, not ShellExecuteA (which is normally what just plain ShellExecute points to). The declare is included in the sample project.

Code:

With TaskDialog1
    .Init
    .MainInstruction = "Let's see some hyperlinking!"
    .Content = "Where else to link to but <a href=""http://www.microsoft.com"">Microsoft.com</a>"
    .IconMain = TD_INFORMATION_ICON
    .Title = "cTaskDialog Project"
    .CommonButtons = TDCBF_CLOSE_BUTTON
    .Flags = TDF_ENABLE_HYPERLINKS
   
    .ShowDialog

    Label1.Caption = "ID of button clicked: " & .ResultMain
    Label2.Caption = "ID of radio button selected: " & .ResultRad
   
End With

Private Sub TaskDialog1_HyperlinkClick(ByVal lPtr As Long)

Call ShellExecuteW(0, 0, lPtr, 0, 0, SW_SHOWNORMAL)

End Sub


Let's talk about custom icons. You can have a custom icon for both the main icon and the footer icon.
Thanks to the brilliant idea of Schmidt over here, the option to specify an icon id from either shell32.dll or imageres.dll, the two main Windows icon libraries, has been added. This massively expands the icons you can show without having to provider an hIcon.
TDF_USE_SHELL32_ICONID, TDF_USE_IMAGERES_ICONID
Simply specify if you're going to use one of those sources by adding the above to the flags, and set the icon to the index you want. Only one can be used, so both header and footer index will come from the chosen DLL. Standard icons (the TDICONS group) work regardless of the source of other icons. NOTE: These do not run from 0-# of icons, so if your icon browser is telling you that, you need to use a different one, otherwise the dialog may display the wrong icon, or not show at all if the id doesn't exist.

Code:

With TaskDialog1
    .Init
    .MainInstruction = "Show me the icons!"
    .Content = "Yeah, that's the stuff."
    .Footer = "Got some footer icon action here too."
    .Flags = TDF_USE_SHELL32_ICONID
    .IconMain = 18
    .IconFooter = 35
    .Title = "cTaskDialog Project"
    .CommonButtons = TDCBF_CLOSE_BUTTON
   
    .ShowDialog
End With


You can also specify a truly custom icon from a .ico file on disk, in your resource file, or anywhere you can get an hIcon from.
The sample project uses a method I adapted from Leandro Ascierto's cMenuImage. It gets around VB's limitations on icons by adding them to the resource file as a custom resource, and not an icon. This way, you can include any size and any color depth and any number of them inside the .ico. Then, the ResIcontoHICON function will give you the hIcon you need for cTaskDialog. But remember, any other function returning an hIcon will work. Icons can also be updated while the dialog is open by another .IconMain= or .IconFooter= statement. You can use a standard icon for main and custom for footer, and vice versa, or both. When you're going to use a custom icon, you must include TDF_USE_HICON_MAIN/TDF_USE_HICON_FOOTER in the flags. If you create an hIcon, don't forget to destroy it when you're done.
The icon size can't really be changed much; the main icon will be distorted but not larger if you give it a larger size, although you can make it a smaller size. The footer icon won't change at all.

Code:

Dim hIconM As Long, hIconF As Long
hIconM = ResIconTohIcon("ICO_CLOCK", 32, 32)
hIconF = ResIconTohIcon("ICO_HEART", 16, 16)
With TaskDialog1
    .Init
    .MainInstruction = "What time is it?"
    .Content = "Is is party time yet???"
    .Footer = "Don't you love TaskDialogIndirect?"
    .Flags = TDF_USE_HICON_MAIN Or TDF_USE_HICON_FOOTER
    .IconMain = hIconM
    .IconFooter = hIconF
    .Title = "cTaskDialog Project"
    .CommonButtons = TDCBF_CLOSE_BUTTON
   
    .ShowDialog

    Label1.Caption = "ID of button clicked: " & .ResultMain
End With
Call DestroyIcon(hIconM)
Call DestroyIcon(hIconF)

Due to the severe limitations on what icons can be put in a VB project res file in the actual icon group, I strongly recommend a different method. But if you want to try anyway I believe you can just set pszIcon.. to its ID, and not set any of the icon flags.

The last basic feature is the verification checkbox. Here's an example with that, and all the other text fields. Note also what happens in this example when no buttons are specified anywhere: the OK button appears by default.

Code:

With TaskDialog1
    .Init
    .MainInstruction = "Let's see all the basic fields."
    .Content = "We can really fit in a lot of organized information now."
    .Title = "cTaskDialog Project"
    .Footer = "Have some footer text."
    .CollapsedControlText = "Click here for some more info."
    .ExpandedControlText = "Click again to hide that extra info."
    .ExpandedInfo = "Here's a whole bunch more information you probably don't need."
    .VerifyText = "Never ever show me this dialog again!"
   
    .IconMain = TD_INFORMATION_ICON
    .IconFooter = TD_ERROR_ICON
   
    .ShowDialog
   
    Label1.Caption = "ID of button clicked: " & .ResultMain
End With


One of the major stylistic differences are the CommandLink buttons. When using the Command Link style, the first line is considered the main text, and lines are made into sub-text. Note that the line is broken with vbLf only; not vbCrLf. vbCrLf results in the text not being smaller on Win7 x64, I haven't tested other systems but it should be the same.
With the custom button sample from above, these changes are made:

Code:

    .Flags = TDF_USE_COMMAND_LINKS
    .AddCustomButton 101, "YeeHaw!" & vbLf & "Put some additional information about the command here."




That covers all the basic functionality.
Download Attachment: cTaskDialog 0.3.3.zip
Attached Files

Nice Textboxes Plus Varius Selectors

$
0
0
Why some functions are so difficult to find. I would like to have some controls without the restrictions for using...this or that themes..manifests or other bad habits..
So i wrote some textboxes. All of them are based in glist (latest edition).
Here I have a TextViewer to display text with line spacing as we wish and wrapping or not. The only limitation is has no drag and drop,and not for this version undo control.. Because is the glist behind this TextViewer can scroll the text holding down the mouse button and doing a move anywhere in the window of the glist

I also have some textboxes with one line only
- a Combobox with auto complete function (shows/hide a listbox of values)
- a Spinner Textbox for a long value. We can alter the value by clicking and writing, by using up down buttons, by using the scroll bar.
- a simple textbox wit centered text that can be edit ...as is, we can use it without edit, just showing text
- a button that can be slide the caption and perform the "click" (by panning right) (2 buttons using here, one to alter the wrapping of the textViewer, and the other to show/hide the paragraphs marks..
- A floating list of values to put in Spinnet TextBbox. We can "call" like a popup menu. See above the spinner textbox, when you right click.

Version 2
- ComboBox - works fine.
- CheckBox
- Info popup in a textbox demonstration
for document type
- Simple undo (undo for deleted marked text and for paragraph changes), use control Z
- Control A (select all)
- Double click select word
- Drag and Drop
you can move or copy from and to same document. double click a marked text show the drag icon. This is not the same as holding down the mouse and move. This function is for moving like using a stick the scroll bar.

Last Version
This version is almost identical to the one before. When we mark text a up or down movement of caret (or cursor) unmark the text. A second touch is about the showing of scrollbar. It was a small appearance of that scroll bar when showing the form who hold the control, that it isn't pretty, especially for that glists where the items are less or equal of viewing lines. A last touch was for document (textviewer class) for the example with file selector, a missing +1 chenage the line for caret in a drag over event when no header used (drawing) in the glist.

For the Selector Example.
Open Load File Selector and open a txt file (UNICODE or not). A new form opens with one text box (the standard one) and one from textviewer class (a wrapper class for glist4 listbox control). From file menu check enable to write and check the other options to see what happen. Also the textviewer resize as we resize the window, and the wrapping is fast, very fast (enable it from file menu). Also see that classic textbox has flickering. No flickering for Textviewer.

If anyone want the scroll bar only, then that code can be found it in Scrollio example, (I wrote the scroll bar for the scrollio control, as an image/drawing viewer, and then I do a merge of that code to the glist, the one with ...millions of items...that I posted here some months ago).

I have started the major task to, and I have exclude file,folder, color and font selectors from M2000 Environment and Interpreter, and now is time to through the classic textbox.



That's All
...for now

Look #5 for latest versions
Attached Images
 
Attached Files

[VB6] NetWkstaUserEnum API wrapper

$
0
0
While most people won't need this I've been seeing threads requesting it lately.

A common problem is that the results of a query against a Jet MDB's active user roster via ADO and SCHEMA_ID_ROSTER returns database client user names and client machine names. But you let all users logon as Jet user "Admin." So you want to try to get Windows logon user names from the machine names.


What NetWkstaUserEnum Does

NetWkstaUserEnum() is a function used to get a list of logged on users at a machine by name. You can also pass it an empty name to get the local machine's logged on users.

This function actually enumerates the user logons and not the users. This includes interactive logons, batch logons, and service logons, so it frequently returns the same name more than once. Since in the course of normal use various system services will impersonate a user to perform functions on their behalf, so a user may be reported even if they have subsequently logged off their interactive session.

There are two "call levels" and Level 1 returns a few additional items most programs won't need.


What WkstaUserEnum.bas Does

This module exposes the EnumUsers() function. This makes Level 0 NetWkstaUserEnum() calls to build a list of user names in the dynamic String array passed to it. As it builds the list it eliminates duplicate entries, making it slightly more useful than some wrapper code I've seen.

You could use Level 1 calls instead if you want the extra info but these additional items aren't too exciting or useful to most programs. If you want this you'll need to decide how to return it, and you may want to eliminate the "duplicate filtering" since the multiple entries for the same user name may not really be unique (others values might vary).


Why Use WkstaUserEnum?

Yes, you can get this information via WMI queries. However WMI is not meant for use in applications, it is an admin scripting tool. It is also fairly "heavy" and depends on the WMI service being installed and running on the local machine and all target systems being queried.


Practical Issues

NetWkstaUserEnum() calls block, and so when querying a remote system there can be delays of many seconds. This is usually because the network is very slow, the remote system is very busy, or the remote system is an oddball device running Samba or something rather than actually being a Windows system.

It also only works for systems that are Windows NT 3.1 or later, or those with a good LAN Manager/MS Networking emulation.

The results returned are a list and may well have multiple user names in most realistic scenarios. It is possible that the first returned result tends to be that of the local console interactive logon (if any) but there are no guarantees. After all, there could be batch logons active with nobody logged on interactively at all!


Requirements

The querying system (running your program) must be Windows NT 4.0 or later. Queried systems should be Windows NT 3.1 or later.

There is no support for Win9x systems at either end.


Usage, Demo

The attached demo shows how easy it is to use. Here is all of the code in the demo's Form1:

Code:

Option Explicit

Private Sub cmdFetch_Click()
    Dim Status As NETAPI_STATUSES
    Dim strUsers() As String
    Dim I As Long

    Status = WkstaUserEnum.EnumUsers(txtServer.Text, strUsers)
    If Status = NERR_SUCCESS Then
        With txtResult
            .Text = ""
            For I = 0 To UBound(strUsers)
                .SelText = strUsers(I)
                .SelText = vbNewLine
            Next
        End With
    ElseIf Status = EXTENDED_EXCEPTION Then
        txtResult.Text = "VB Exception " & CStr(WkstaUserEnum.LastError) & " " _
                      & WkstaUserEnum.LastDescription
    Else
        txtResult.Text = "System Error " & CStr(WkstaUserEnum.LastError) & " " _
                      & WkstaUserEnum.LastDescription
    End If
    txtServer.SetFocus
End Sub

Attached Files

What is the best way to resize only certain things on a form?

$
0
0
I'm coding a chat/server client and I'm having some issues trying to get resizing working correctly.

I have a chat form that looks like this.

Name:  dlc4x.jpg
Views: 57
Size:  26.2 KB

I'm wanting to keep the top labels, textbox, and buttons the same size and in the same exact spot. I want to adjust the chat textbox, the listbox, and the textbox at the bottom that you type the message to. The send button I want to stay the same size also and always to the right of the send textbox. I'm having a really hard time trying to figure out how to code the resizing part of the code.

I could really use some assistance I've tried many things like.

txtchat.height = me.scaleheight - 100 adding the 100 in there to try and take off some for the controls on the top of the form. Also tried

txtchat.height = me.scaleheight - txtsend.height - 100 and a ton of other things. I guess I just don't understand how this resizing works. Any help would be appreciated.
Attached Images
 

[RESOLVED] What is the best way to resize only certain things on a form?

$
0
0
I'm coding a chat/server client and I'm having some issues trying to get resizing working correctly.

I have a chat form that looks like this.

Name:  dlc4x.jpg
Views: 81
Size:  26.2 KB

I'm wanting to keep the top labels, textbox, and buttons the same size and in the same exact spot. I want to adjust the chat textbox, the listbox, and the textbox at the bottom that you type the message to. The send button I want to stay the same size also and always to the right of the send textbox. I'm having a really hard time trying to figure out how to code the resizing part of the code.

I could really use some assistance I've tried many things like.

txtchat.height = me.scaleheight - 100 adding the 100 in there to try and take off some for the controls on the top of the form. Also tried

txtchat.height = me.scaleheight - txtsend.height - 100 and a ton of other things. I guess I just don't understand how this resizing works. Any help would be appreciated.
Attached Images
 

[VB6] modLockEnumCase.bas - Enforce Case of Enums

$
0
0
The VB6 IDE has an annoying quirk when it comes to the case of Enum members. Unlike with other identifiers, the IDE doesn't enforce the case of an Enum member as it was declared in the Enum block. That usually causes an Enum member that was manually written to lose its original case, unless a coder typed it carefully enough. The prevalent workaround for this bug is to redeclare the identifiers inside an #If...Then...#End If directive

Code:

Private Enum Constants
    Const1
    Const2
    Const3
End Enum
#If False Then
    Dim
Const1, Const2, Const3
#End If

However, if a project contains a lot of Enums, redeclaring the members in each of them can get quite tedious fast. Nobody seems to have submitted yet a routine to automate this process here in the VB6 CodeBank, so I'm sharing this code snippet I've had for some time now.

Code:

Attribute VB_Name = "modLockEnumCase"
Option Explicit

'modLockEnumCase.bas usage:
'1. Add to project.
'2. Select entire Enum block.
'3. Copy to Clipboard.
'4. Run LockEnumCase() from the Immediate Window. Optionally *suggest* length of each line.
'5. Paste after the Enum block.
'6. Remove from project when no longer needed.


Public Sub LockEnumCase(Optional ByVal LineLen As Integer = 80) 'Adjust length of output lines as desired
Attribute LockEnumCase.VB_Description = "Enforces the case of Enumerations via Conditional Compiler Directives."
    Dim sBlock As String, sLine As String, sText As String, oMatch As Object 'Match

  'See if there's anything to process; quit if no text was copied

    If Clipboard.GetFormat(vbCFText) Then sText = Clipboard.GetText Else Exit Sub
  'Prepend the conditional compiler directive that is set to False
    sBlock = "#If False Then" & vbNewLine
  'Dimension variables that reuses the Enum members' names
    sLine = "Dim "

    With CreateObject("VBScript.RegExp") 'New RegExp
        .Global = True
        .MultiLine = True

      'Strip all comments
      .Pattern = " +'.*$"
        sText = .Replace(sText, vbNullString)

      'Exclude Enum statements
      .Pattern = "(\b(Private|Public)? Enum [A-Za-z]\w*\b)|(\bEnd Enum\b)"
        sText = .Replace(sText, vbNullString)

      'Split multiple expressions in a single line into their own lines
        If InStrB(sText, ":") Then sText = Replace(sText, ":", vbNewLine)

      'This should match most Enum member names, including those enclosed with []
      .Pattern = "^ *([A-Za-z]\w*|\[.+\]) *(?:=|$)"

        For Each oMatch In .Execute(sText)
            sLine = sLine & (oMatch.SubMatches(0&) & ", ")

          'Check if the string being built is exceeding
          'the *suggested* limit of each output line

            If Len(sLine) >= LineLen Then
              'If so, commit this line to the output string
                sBlock = sBlock & (sLine & "_")
              'Begin anew at the next line
                sLine = vbNewLine
            End If
        Next
    End With


  'Finish the conditional compiler directive block, removing empty lines as needed
    sBlock = sBlock & (IIf(sLine <> vbNewLine, sLine, vbNullString) _
                    & vbNewLine & "#End If" & vbNewLine)
  'Overwrite the last comma with a space
    Mid$(sBlock, InStrRev(sBlock, ",")) = " "
  'Try to erase the last underscore on the last line, if present
    On Error Resume Next
    Mid$(
sBlock, InStrRev(sBlock, "_" & vbNewLine & "#")) = " "
    On Error GoTo 0

  'Copy back to the Clipboard
    Clipboard.Clear
    Clipboard.SetText sBlock
End Sub

Attached Files

[VB6] API Open With Dialog with enhanced functionality

$
0
0
All the methods I've seen for bringing up the Open With dialog use rundll32. But Windows Vista and above has a better option: the SHOpenWithDialog API call. This allows a number of different options in addition to modality. After searching, it seems no one has posted a VB6 implementation yet, so I thought others might like the idea of using this as much as I did.


Requirements: The API call is only available on Vista or higher.

Code:

Option Explicit

'Module: mOpenWith
'Version: 0.1
'Author: fafalone
'Purpose: Vista and above provides an API call for the Open With dialog, which offers more options
'        than the previous typical method of using rundll

Public Declare Function SHOpenWithDialog Lib "shell32" (ByVal hWnd As Long, poainfo As OPENASINFO) As Long

Public Enum OPEN_AS_INFO_FLAGS
    OAIF_ALLOW_REGISTRATION = 1 'Enable the "always use this program" checkbox. If not passed, it will be disabled.
    OAIF_REGISTER_EXT = 2 'Do the registration after the user hits the OK button.
    OAIF_EXEC = 4 'Execute file after registering.
    OAIF_FORCE_REGISTRATION = 8 'Force the Always use this program checkbox to be checked. Typically, you won't use the OAIF_ALLOW_REGISTRATION flag when you pass this value.
    OAIF_HIDE_REGISTRATION = 20 'Introduced in Windows Vista. Hide the Always use this program checkbox. If this flag is specified, the OAIF_ALLOW_REGISTRATION and OAIF_FORCE_REGISTRATION flags will be ignored.
    OAIF_URL_PROTOCOL = 40 'Introduced in Windows Vista. The value for the extension that is passed is actually a protocol, so the Open With dialog box should show applications that are registered as capable of handling that protocol.
    OAIF_FILE_IS_URI = 80 'Introduced in Windows 8. The location pointed to by the pcszFile parameter is given as a URI.
End Enum

Public Type OPENASINFO
    pcszFile As Long
    pcszClass As Long 'file type description for registering the type with 'always open', if not set uses extension, as in 'XYZ File'
    oafInFlags As OPEN_AS_INFO_FLAGS
End Type



Public Function OpenWith(sFile As String, lFlags As OPEN_AS_INFO_FLAGS, Optional hWndParent As Long, Optional sClass As String) As Long
Dim oai As OPENASINFO
oai.pcszFile = StrPtr(sFile)
oai.oafInFlags = lFlags
If sClass <> "" Then oai.pcszClass = StrPtr(sClass)
OpenWith = SHOpenWithDialog(hWndParent, oai)
End Function

The sample project attached contains a form that calls the OpenWith function.

OpenWith(sFile As String, lFlags As OPEN_AS_INFO_FLAGS, Optional hWndParent As Long, Optional sClass As String)

sFile - The file to be opened
lFlags - See the descriptions in the BAS; you'll usually want to include OAIF_EXEC to open the file afterwards, and OAIF_ALLOW_REGISTRATION to enable the 'always use this program' box.
hWndParent - You can specify an owner window (e.g. Form1.hWnd) and the dialog will be modal to that form (you can't click on anything on the form until the dialog closes).
sClass - You can optionally specify a file type description for registering the type for always open. If not specified, the file extension would be used (e.g. XYZ File).

Note: Since this is a Unicode function (it takes lpcwstr's, hence the need for strptr()), it should handle unicode file names and unicode path lengths without issue.
Attached Files

[VB6] Image Recovery from Project Files

$
0
0
Not a groundbreaking project by any means. This little project can retrieve images saved within an uncompiled resource file or within project binary files (frx, ctx, dsx, dox, pgx).

Resource files. How to retrieve using just VB functions...
1) BMP: LoadResPicture & SavePicture will retrieve & save in bitmap format
2) ICO: LoadResPicture & SavePicture will only save the extracted icon. If icon contains multiple images, the others will be lost
-- LoadResData for icons generates error.
3) CUR: Same as icons, but worse: changes format from cursor to icon
-- LoadResData for cursors, only bitmap data returned, not cursor header
4) CUSTOM section. Use LoadResData then save returned array to disk.

If you have the binary files and the actual associated non-binary file to go with it, then...
1) BMP. Note: JPG & GIF images in these binary files maintain their original image format
a. In code, use SavePicture ControlName.Picture
b. In design mode, click on control that has the bitmap image assigned. Find Picture in the property sheet & double click on it. Press Ctrl+C & paste into Paint & then save
2) ICO/CUR. Cannot get the image, VB will not copy them to the clipboard
in code, use SavePicture ControlName.Picture. But same restrictions apply as with LoadResPicture mentioned above for resource files
3) WMF/EMF. In code, use SavePicture ControlName.Picture
-- Should be able to copy to clipboard similar to VBs



But if you want a solution that isn't limited to noted restrictions above. This project is one.

Maybe there are other methods out & about. But honestly, not many people will find this useful until they have a corrupted frm file & their only copies of the images were in the frx file which may not be useable to VB any longer, but usable to this project if that frx itself isn't corrupted.
Attached Images
 
Attached Files
Viewing all 1324 articles
Browse latest View live




Latest Images