VB6: How to switch to pixels instead of twips - vb6

I am refactoring a VB6 application. The measurements of any of the controls are in twips. Is it possible in VB6 to set a control to use pixels instead of twips? Thanks

I worked extensively with scalemode back in the day and all I can say is don't bother. It wasn't properly universally supported, which meant that you'll end up converting back to twips for some things anyway.
VB6 is twips based, like it or not, so if you try to do things pixel based, you'll be fighting the current the whole way.
Fortunately VB.net finally ended all that, and is completely pixel based, you can still alter you viewport scaling but .net seems to handle that much better than Vb6.

dim iInPixels as integer
dim iInTwips as integer
iInPixels = 200
iInTwips = iInPixels * Screen.TwipsPerPixelX
iInPixels = iInTwips / Screen.TwipsPerPixelX
As #drventure said, you'll be rowing against the current the whole way, but it really isn't all that bad, as long as you can isolate the logic to a single spot.

Does the ScaleMode Property help?
Returns or sets a value indicating the unit of measurement for coordinates of an object when using graphics methods or when positioning controls.

Microsoft Knowledge Base article: How to Convert Twips to Pixels
The link above is for Access VBA but will work with VB6 as well. I'm not aware of native VB6 functionality to do what you need. From what I remember ScaleMode will not work for what you want to do (despite the fact that it seems to exist to solve your exact problem).
EDIT: As I'm thinking about it, ScaleMode did not solve my problem that I had at the time. Depending on what you are trying to do, it may solve your problem just fine. I'd certainly try that first since it will produce simpler, more maintainable code.

I did it this way.
I got the Twips from Form1.Picture.Width and by dividing with pixelize you get pixels ANYWHERE in VB6 Script.
In General Declarations
Const pixelize As Double = 26.45833333
Command3.Caption = "Pixels: " & Int(Form1.Picture.Width / pixelize) & "x" & Int(Form1.Picture.Height / pixelize)
Works for me, maybe you are helped.

Related

is there a simple way of obtaining the RGB of the brush used to erase the window background?

I'm looking for a simpler way (if there is one) of finding out what RGB is used by the brush that Windows uses to erase a window background.
The problem I'm trying to solve in the most elegant way is as follows:
When registering the class, I specify a brush this way:
hbrBackground := GetSysColorBrush(COLOR_WINDOW);
when processing the WM_PAINT, I'm using ExtTextOut specifying ETO_OPAQUE and the rectangle (so it clears it.)
Currently, I am using:
SetBkColor(dc, GetSysColor(COLOR_WINDOW));
That has an obvious downside, if the brush used when registering the class changes then, the programmer has to remember or be aware that the same change must be made in the SetBkColor instruction found in WM_PAINT. That's not good.
One way of solving the problem is to use GetClassLongPtr to get the background brush then, use GetObject on the brush to get its LOGBRUSH which contains the brush's RGB which can be passed to SetBkColor.
My question is: is using GetClassLongPtr followed by GetObject the simplest way of getting the RGB value I need to pass to SetBkColor ? I'm hoping there is a simpler (more straightforward) way than that.
Thank you very much for your help.
PS: I'm looking for a straight API solution in C/C++ or Delphi. No .net or any other framework solution.

Smooth animation of three shapes in SciLab

This answer provides a nice way to make smooth animations in SciLab. I now have to write a simulation of a body attached to two strings (and therefore its movement regarding some additional forces).
The code in the link works well to render movement of a single point and, unfortunately, I didn't manage to make an animation of a point + two lines using this method. If someone is curious, I tried this code to do it:
frametime=(tk-t0)/Nt//defining the waitnig time
plot(Y(1,1),Y(2,1),"o")//plotting the point
plot([0;Y(1,1)],[0;Y(2,1)],style=1)
plot([D;Y(1,1)],[0;Y(2,1)],style=1)//plotting the two initial lines
h1_compound = gce();
h_point=h1_compound.children
h_point.mark_size = 20;
h_point.mark_background = 2;
h_line1=h_compound.children
h_line2=h_compound.children
//h_axes = gca();
//h_axes.data_bounds = [0,-1;10,1];
realtimeinit(frametime);
for i=1:Nt//my vectors have Nt points
realtime(i);//wait "frametime" seconds before drawing the new position
h_point.data=[Y(1,i),Y(2,i)];
h_line1.data=[[0;Y(1,i)],[0;Y(2,i)]]
h_line2.data=[[D;Y(1,i)],[0;Y(2,i)]]
end
The question is: is there any way to make an animation of three shapes without making axes blink (as it is with the window refreshment) or other wierd stuff?
Since you didn't create a MCVE I can't reproduce your exact problem. But you may try to add drawlater(); before, and drawnow(); after your data modification to see if it does help with blinking or not.
Or you may get much better looking result by saving your plots in every round with xs2gif and assemble the animation with another gifmaker progam (there are free online sites to do this, however with some limitations). If you need to present your result, you should do this step anyway.

Using VBA to insert and keep images in file - Excel 2013

I'm working on a macro for a friend of mine who needs to import a set of images in an excel document and later use this document on other computers. The problem I encountered is that when opening this document on a different computer, all the images are gone and instead you get these little error signs, indicating that the image path could not be found.
I have developed the macro on my own computer where I have Excel 2007 and for me, the code works perfectly fine. My friend uses Excel 2013 and apparently, there seems to be a major difference on how those 2 versions deal with the image importing and saving.
Overall, I found 2 different ways how to insert images. The first one I tried was something similar to this:
Set pic = ActiveSheet.Pictures.Insert("C:\documents\somepicture.jpg")
The second way of doing this looked like this:
Set pic = Application.ActiveSheet.Shapes.AddPicture("C:\documents\somepicture.jpg", False, True, 1, 1, 1, 1)
In the documentation for this 2nd approach it is said that the 3rd paramenter (which is True here) is responsible for saving the picture with the document.
However, both these approaches look more or less the same in the end result: They work fine for me but won't work if they are executed on my friends pc with Excel 2013. So what I need is a work-around for the newer Excel versions (I read somewhere that from Excel 2010 upwards, there is a bug or something like that with these image import methods).
In all my uses, Adding a picture with Insert makes a reference to a file on your harddrive, for whatever reason if you want the image to be embedded in the file you have to add a shape and then put the image on the shape using the AddPicture (like you use), I have never had any issues with this.
Also you are giving the picture a height and width of 1 pixel, You will almost never be able to see that true setting that higher as below:
Application.ActiveSheet.Shapes.AddPicture "C:\documents\somepicture.jpg", False, True, 1, 1, 100, 100
I have a feeling it was working all along and you just never saw the picture cause it was too small.
The first snippet works just fine, but it does not allow picture positioning (i.e. if you need a pic placed at some certain range), so I made something that works nicely with positioning available, based on the second solution, such as it is shown below.
Dim r As Range
Dim pic As Shape
Set r = ActiveSheet.Range("A34:Q58")
Set pic = ActiveSheet.Shapes.AddPicture(ThisWorkbook.Path & "\FracAnalysis.png", _
linktofile:=msoFalse, savewithdocument:=msoCTrue, Left:=0, Top:=0, Width:=-1, Height:=-1)
With pic
.LockAspectRatio = msoFalse
.Top = r.Top
.Left = r.Left
.Width = r.Width
.Height = r.Height
End with
Previous answer has been really useful! I just wanted to add the reference to the method parameters (I thought the width and height were in pixels, turns out they're in points):
https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.shapes.addpicture.ASPX
I usually run a macro that downloads images from a server into files that are then forwarded to clients who do not have access to that server. My coding is quite basic so I'll just copy the particular line I use to insert the picture:
Set pic = ActiveSheet.Shapes.AddPicture(Filename:="C:\documents\somepicture.jpg", _
linktofile:=msoFalse, savewithdocument:=msoCTrue, Left:=0, Top:=0, Width:=-1, Height:=-1)
I know its technically the same code as the one you proposed, but try using msoCTrue and msoFalse. I seem to recall that being part of the issues. Let me know if it works and maybe we can try something else. It works for me, so we should be able to get it to work for you.

Calculate actual size needed for a MATLAB uicontrol

I'm trying to calculate the actual size needed for uicontrols in a GUI so the GUI can resize itself appropriately. My problem is that the Extent property of a uicontrol is only the text area, and I can't find a way to determine the size of the surrounding control (such as the down arrow in a popup or the margin of an edit control). Is there a way to get the size of the decorations on a control?
I saw this related question on MATLAB Answers, which looked like it ended with no solution as well.
Edit:
For example, I want to calculate how big this popup should be to avoid cutting off the contents:
uicontrol('style', 'popup', 'string', {'a long string'})
Extent only tells me how big "a long string" is, and I still don't know how big to make the popup. I want a way to determine how much extra space is needed on the user's display (without assuming which OS or font sizes they use).
You can use get(hObject,'extent') to find out how much space the string contained in the uicontrol takes up. You can see if this is larger than the uicontrol's position.
The uicontrol Position property gives you the height and width of the bounding rectangle for the control. This has always worked for me. Is there a control where this property does not provide enough information?
If the GUI you're building can be assembled exclusively from Java components, you can use MATLAB's Java integration to create and drive a window using Java Swing components (all from M-code). That sidesteps the problem entirely, since the Java layout managers can do UI layout properly.

How can I resize my vb6 program so that it automatically fits in any screen resolution?

How can I have a vb6 program which opens correctly in 1280*1024 but when switched to other resolutions say 640*480 i can only see half of the screen. how to re-size my vb6 program so that it automatically fits in any screen resolution?
You need to use the Screen object, this will always give you the current resolution in pixels:
Dim screenwidth,screenheight As Single
screenwidth = Screen.Width \ Screen.TwipsPerPixelX
screenheight = Screen.Height \ Screen.TwipsPerPixelY
Usually a Form amenable to resizing has controls that lend themselves to a "flow" layout. Often this is something like a TextBox, grid control, etc. that supports scrollbars. You shrink/grow such controls as required after allocating positions for (i.e. moving) the fixed-size elements like buttons and such.
For a busy Form with lots of fixed size controls that isn't "document oriented" there is no set answer. Sometimes creating a scrollable Form makes sense but usually it doesn't.
Some people try to resize "fixed" elements, change fonts sizes, etc. This can produce results of mixed quality though, sometimes good and sometimes not.
Considerations about the Form size are best made up front as part of the design process. For some applications it might be better to decide on a minimum supported Form size. In other cases you may have to break things up with dialog Forms or tab controls.
There's no easy way to do this in VB6, like there is in .Net. You have to manually resize everything in the form's Resized event handler based on the new form's client size. It's a pain, and a huge mess, but it's the only way to do it.
Correction: There's never only one way to do things, but I've been programming VB6 for several years, and usually just writing it into the Resize handler is straightforward enough, and I haven't found any good way to do it other than that.
Have you tried any 3rd party tools for doing this? Here's (a free) one that seems to work :-
ActiveResize Control Lite - I created a quick project to try it and it does what it says on the tin!
The lite version has some limitions such as number of forms in project, number of controls on form etc. You can also buy a Standard or Professional version if you need more functionality.
I know we've spent countless hours trying to implement our own resizing code only to remove it all and fix the location of most controls, move a few to make it look better and limit the min/max functionality of the form - none of which give a nice user experience. If we needed to do it again I probably use this control (or a similar one) just for the time savings.
I use ComponentOne SizerOne
The C1Elastic control allow from resizing and maintain the aspect ratio, resizing the inside controls on the setting you defined.
It's not free, but it payed itself with all the time I saved.
Form1.Height = Screen.Height
Form1.Width = Screen.Width
This code sets form size according to screen resolution.
"ActiveResize Control Lite" ActiveX tool is limited to 20 controls per form.
Once we know the screen resolution, there are a number of things you can do.
• The easiest solution would be do design different form to accommodate the four most popular monitor resolutions – 640 x 480, 800 x 600, 1024 x 768, and 1600 x 1200.
• Alternatively, we could write code that dynamically resizes and relocates every control on the form, based on the screen resolution – not an easy undertaking!
• Third party controls that resize the controls based on the screen resolution are quite effective. On the whole, though, it's better to just avoid this kind of problem, if you can. For example, see Creating Flexible Forms in Visual Basic (Flexi-Forms) at codeguru.com
To auto fit screen resolution you need to download an active x, drag it on your conform.
Search for "veg gold vb6.0 screen Resize".

Resources