Thursday, September 29, 2011

ssTitleBar

ssTitleBar is my final design for a title bar class. This does not mean though that the themes shown here will be the final ones.  From time to time, I still get the urge to create new looks or themes.  This class is the successor of my early title bar classes up to ssTBNextGen.  History of those can be seen in some of my early posts including this one: http://weblogs.foxite.com/sandstorm36/archive/2009/12/15/9724.aspx

The major difference between those early classes and this now is that ssSkinner is embedded here to give users the ability to hot-skin (change color any time) the title bar.  Below is my favorite theme, theme 8:

And here are the other themes I previously created:

You may wonder maybe why I created ssTitleBar when what is currently in the market now is Glass Title Bars.  The answer to that is I wanted my forms to be unique and totally independent of an OS Theme.  It will not matter if you will be running XP, 7, 98 or any other OS.  The appearance of my forms will be uniform, not to mention that VFP Projects powered by ssClasses will really be unique.

Another side-feature that ssTitleBar class has is that unlike the standard Title Bar, you can put objects on top of it like command buttons, a clock maybe, a printer icon or label maybe?   Well actually it is up to you what you wanted to do with this later...


For the current listing of ssClasses, click this link:  http://sandstorm36.blogspot.com/2011/10/ssclasses-components-list.html


ssContainer2 (new)

I don't know what prompted me to create a new container class which will replace ssContainer but that is what has happened.  Maybe because of the curvature feature that was requested to me to by MK Sharma last time or maybe some other things.  But the outcome I deem is nice.  Take a look at how ssClasses affects the appearance of a form.  Shown below is a form with standard objects  only (with the exception of Ony Too's datepicker class):


And this is how it looks like with just the ssTitlebar class and the new ssContainer2 class:

Friday, September 23, 2011

Glass PageFrame (sort of)

With the coming of Windows 7 glass style, everybody seems to want to have its effect incorporated into our projects.  Though this is really not Glassy as it is more transparent, I still decided to call this Glass PageFrame as I know it will attract more attention (Nasty reasoning), LOL!
This is very simple to implement but the impact is cool.
Ready?  Then follow these 7 steps (some are optional):
1. Initially hide the tabs of the PageFrame
2. Themes property should be set to .F.
3.  Change the tabs’ Backstyle to 0 (transparent).  Note that while tabs are shown (default), VFP will not allow you to change the backstyle that is why we need to hide those first.
4.  Add a container inside pages so the inner part of the pageframe will appear normal and only those outside of that container will appear transparent
5.  Optionally, you can change the style of the container into 3 (Themed) which adds effect to the Glass-like interface you wanted to achieve
6.  Change the forecolor of the tabs to mix properly with the background
7.  Finally, show the tabs again.
And that is it.  Told you it is very simple.  Enjoy!


And here are the codes:


Source code

Local oForm As Form
oForm = Createobject('GlassPage')
oForm.Show(1)
Return
 
Define Class GlassPage As Form
	AutoCenter = .T.
	Height = 370
	Width = 341
	Caption = "Glass PageFrame"
	Picture = Addbs(Getenv("WinDir"))+"Prairie Wind.bmp"
 
	Add Object label1 As Label With;
		left = 24,;
		Top = 23,;
		Width = 300,;
		WordWrap = .T.,;
		AutoSize = .T.,;
		BackStyle = 0,;
		FontSize = 8,;
		FontName = "Tahoma",;
		ForeColor = RGB(255,255,255),;
		Caption = "This simple demonstration will show how to make a PageFrame "+;
		"tranparent.  Seems nice to combine with Windows 7 Glass Effect. "+;
		CHR(13)+CHR(10)+CHR(13)+CHR(10)+;
		"Additional Effect has been implemented on the container inside the pageframe "+;
		"via Style property (as shown on page1)."
 
	Add Object GlassPage As PageFrame With ;
		Left = 22, Top = 120, Width = 295, Height = 200, PageCount = 2,;
		Themes = .F., Tabs = .F., TabStyle = 1
 
		ADD OBJECT command1 as commandbutton WITH ;
		left = 22, top = 330, Caption = "\<Change Background", AutoSize = .T.
 
	Procedure Load
 
	Endproc
 
	Procedure Init
		With Thisform.GlassPage.Page1
		    .BackStyle = 0
			.Caption = "Master"
			.ForeColor = Rgb(255,255,0)
			.AddObject("Cont1","Container")
			With .Cont1
				.Top = 10
				.Left = 10
				.Visible = .T.
				.BackStyle = 1
				.Width = 270
				.Height = 145
				.SpecialEffect = 1
				.Style = 3
			Endwith
		Endwith
		With Thisform.GlassPage.Page2
		    .BackStyle = 0
			.Caption = "Transactions"
			.ForeColor = Rgb(255,255,0)
			.AddObject("Cont1","Container")
			With .Cont1
				.Top = 10
				.Left = 10
				.Visible = .T.
				.BackStyle = 1
				.Width = 270
				.Height = 145
				.SpecialEffect = 1
				.BackColor = RGB(202,202,255)
			Endwith
		Endwith
		Thisform.GlassPage.Tabs=.T.
	ENDPROC
 
	PROCEDURE Command1.Click
	   thisform.Picture = GETPICT()
	ENDPROC 
 
Enddefine

NOFILTER Clause on an SQL SELECT, when to use?

I believe some VFP developers are still wondering what this clause is all about so I will try to explain things based on my perspective.  NOFILTER clause is given to us to ensure that a true cursor and not just a filtered result of the source table (FROM) is created.   

When is it needed?  The basic answer is if you are performing an SQL SELECT ... FROM  .. a single table  with no joins whatsoever and no extra new field created.  Without adding the NOFILTER clause, what will happen is you will only have a filtered result of the source single table.  That you are still working on the same table but just a filtered result.

Whereas what most of us needed is a true cursor or something that is independent and separate from the source table.

But is that clause really needed in ALL SQL SELECT commands?  The answer is yes and no!

Yes - if you are not familiar when it is needed, then to be safe put NOFILTER clause on every SQL SELECTs.

No - If you already knew (which I hope this post can assist you in learning) where it is needed or not as there are conditions where NOFILTER will be automatic, or to rephrase, a true cursor will be created even without us placing that clause and these are:
  • If READWRITE clause is used
  • If SQL SELECT involves two or more tables
  • When GROUP BY clause is used
  • When calculated columns are done like DISTINCT, TOP, PERCENT 
  • When Aggregate functions are used such as AVG(), CNT(), MAX(), MIN() or SUM().
  • When you change a field type into something else via CAST()
  • When a result of SQL SELECT does not result to fully optimizable cursor (like when a new field is created with something like this):
Select *, .F. As NewField From MyTable Into Cursor junk


Mandatory NOFILTER

Here is another thing you need to remember.  When performing another SQL SELECT ... FROM (a cursor), then NOFILTER becomes mandatory on first cursor.

SELECT * FROM Table1 INTO CURSOR Cursor1 NOFILTER


Without the NOFILTER clause above, this 2nd SQL SELECT will fail:

SELECT * FROM Cursor1 INTO CURSOR Cursor2 NOFILTER



Closing Words:

We add NOFILTER clause to instruct VFP to create a true cursor or a cursor that is separate and different than the source table.   But the risk of having a filtered result only if records comes just from a single source table with no JOINs whatsoever.  The moment you combine fields from different tables, that risk goes away.  The moment you created something new to the existing fields like changing its field type via CAST(), then it goes away.  Or perform aggregate functions because that will create a new field as well.

However, since most of us needs a true cursor, then even when some of the conditions I mentioned above will automatically result to VFP creating a true cursor, if you are still  getting confused when it is needed or not, then just issue NOFILTER clause.

Learning mdot Usage

Seeing that there are still a lot of VFP users confused with the usage of MDOT (m. prefix), I decided to create simple explanations regarding this.

When mdot usage is mentioned, a lot of developers argue about whether it is really needed or not.  And as usual with developing there are a lot of ways to do things (skin a cat as Mike Yearwood fondly says) and so every time a thread or a post is started regarding this, it came out the argument seems to be endless.

Originally I titled this “Delving into (un)popular argument, MDOT prefix” because it is a popular argument where threads became long but some think of it as an unpopular way. LOL!  Later I decided to simply title it “Learning mdot Usage”.

Well I am not here to argue whether mdot is really needed or not.  What I am after here is if you will decide to use this, at least you know how properly.  Fair enough?  Then let us go on with the topic:
Let us take a look at this equation:

WholeName = FirstName + ” ” + LastName

Wednesday, September 14, 2011

Get a document's paper size via automation in VFP

Here is a question inside Foxite that took my interest:

how to make code this in vfp, to get the Paper's Size of the document file in (MS OFFICE)?

So I also thought, how?  And I can't think of any other way but automation.  Problem though is it seems you have to recompute the page width and height before you can attain the proper result as those are computed inside Word via "InchesToPoints" and I cannot find a property to get that computed result.  Solution? Try to compute it yourself. :)

Anyway, this seem to work.  Maybe there is a better way than this but this is what I can think of right now:


*******Beginning of Code

LOCAL loWord as word.application, lnHeight, lnWidth, lcSize, lcPaperSize
loWord = CREATEOBJECT("word.application")
lcFile = GETFILE("doc,docx")
loWord.Documents.Open(m.lcFile)
lnHeight = ROUND((loWord.Selection.PageSetup.PageHeight/72.0231),2)
lnWidth = ROUND((loWord.Selection.PageSetup.PageWidth/71.98911),2)
lcSize = TRANSFORM(m.lnWidth)+"x"+TRANSFORM(m.lnHeight)
DO CASE
   CASE m.lcSize = "8.50x11" OR m.lcSize = "11x8.50"
     lcPaperSize = "Letter"
   CASE m.lcSize = "8.50x14" OR m.lcSize = "14x8.50"
     lcPaperSize = "Legal"
   CASE m.lcSize = "11x16.99" OR m.lcSize = "16.99x11"
     lcPaperSize = "Tabloid"
   * and so on......
   OTHERWISE
   lcPaperSize = "Unrecognized Size"
ENDCASE
MESSAGEBOX(m.lcPaperSize)
loWord.Quit

******* End of Code


If you think this approach will work on your side, better create a table to store the widths, heights and paper sizes; and use that table to get the appropriate document's paper size. Widths and Heights should be stored as numeric. I just want to show here how we can see things like (8.5x11 for letter) but best save those as numeric and seek those numeric values in the table itself.  Also as you can see, you can determine further if the document is in landscape or portrait, i.e., if width is bigger than height, it is landscape; otherwise portrait.

And like some of my blogs, I decided to post it here so maybe some other non-members of foxite who will find this somewhat useful  can maybe implement this on their side.  Enjoy!