Tuesday, December 30, 2014

Enumerate and Kill Selected Windows Processess


A question inside Foxite was raised yesterday requesting for a way to kill selected Windows processeses using API calls as what we normally use is the scripting way.  And googling around, there are ways shown by several developers; but none, AFAIK, that terminates successfully a process on each run/attempt.  

My first attempt yesterday combining information I gleamed across the web from several developers were not able to close the target process on every run.  Digging further, one fault I see is my usage of GetModuleFileNameEx is failing to get a proper result thus skipping onto the next process among processes list.  

Friday, December 19, 2014

xBox (a Textbox Control class)

Release 4

  • Made the appearance cleaner by imitating a plain textbox so when you resize on form during design time, you will see the borders cleanly
  • Fixed seeding initial Value via PEM
  • Added seeding via ExtraValue property which displays the correct Value counterpart  
  • Used inherent Picture property for alternate icon.  Removed icon property as that is just a waste of extra unneeded property. Although on form, when a picture for icon is selected, the icon image is shown tiled on the class
  • Added ControlSource, PasswordChar, ReadOnly, FontBold and FontItalic properties

Release 3

Color Toggling on Enabling/Disabling the class - Fixed

Seeding the class via .Value does not perform an AutoComp resulting to .ExtraValue giving a wrong result. Fixed that. However, seeding values to other xBoxes on the form with each having an AutoComp feature enabled short-circuits it; as each tries to perform an AutoComp search during when values are changed.

Solution is to ensure that only the active xBox will perform an AutoComp search. So now, you can do something like this: 

*xBox1's InterActiveChange
*  where search is made and seeding other xBoxes as we type
thisform.xBox2.Value = field2
thisform.xBox3.Value = field3
thisform.xBox4.Value = field6


And only xBox1 will perform the AutoComp search and the others will simply receive the values. Anyway, there is no need for the record pointer to change on those 3 others.

Caveat:

When seeding an xBox where you want it to perform an AutoComp search, then you have to ensure it is the active object in the form. Something like this:

Thisform.xBox1.SetFocus
Thisform.xBox1.Value = 'Whatever'

Say like when you open another form where you want to seed an xBox some value from the calling form and later would also like to reflect the .ExtraValue back, then you have to set focus onto it before the value is seeded.

If you are not after the .ExtraValue though and is only after the .Value, then no need to SetFocus on the class.

Tuesday, November 18, 2014

Encapsulating Popup Calls Within Forms


One of my dissatisfaction when creating a popup shortcut via Define Popup and later On Selection Popup or On Selection Bar commands is its insistence of not accepting Thisform reference.  Something like this:

Define Popup PopFaves From Mrow(),Mcol() Margin SHORTCUT
Define Bar 1 Of PopFaves Prompt "Add to My Favorite"
Define Bar 2 Of PopFaves Prompt "Remove from My Favorite"
Define Bar 3 Of PopFaves Prompt "Show My Favorite"
On Selection Popup PopFaves Thisform._SubFave(Bar(), m.lcCaption)
Activate Popup PopFaves

Monday, October 27, 2014

Right-Click on TreeView

I created last time a "My Favorite" popup menu for my ERP app.  This allows my users to easily jump from one module to another without the need to close what they are working on.  The hotkey is F5.   Each of my users have their own My Favorite as well so they can control themselves what they wanted to be there (those modules they have access to).



I used Ctrl+F to add or remove items on the Favorite Menu utilizing the Selected/Highlighted node from the ActiveX TreeView Control (MSComctlLib.TreeCtrl.2) as when I look for a right-click event back then, I cannot find one.  And I do not want to waste my time on finding that missing Right-Click event as all I wanted is a quick fix for my need.

Friday, October 24, 2014

Easy ways to Capture images

I have not blogged for a long time and you guys know why.  Anyway, here is something that may be useful to you so I am making this entry here.  This is about FoxForm shared to us in Foxite Forum.  This combined with other things will allow us to easily capture our form, our app's screen and the desktop itself; with only few lines of codes.  In addition, you can send those captured images as well direct to printer.  Here are the steps:


Friday, September 12, 2014

For you Kuya Obet and for OFWs!

Some of my friends know that my eldest brother recently passed away at a very young age of 46.  We were devastated as it is totally unexpected. During those times I repeatedly thought of creating an entry here because I wanted to immortalize my Brother's memories.  I have done that for other people, so why should I not do it for my departed Brother (Kuya Obet)?

The problem I have is how can I put into words my brother's story without boring readers.  Why am I so concerned about it?  Well any writer's goal is to make the topic interesting that the readers will take time to read the entirety.  Otherwise my goal of introducing my late brother to the world will fail.  Anyway, I will try my best and I hope I will do good here.  The stories come from my memories and from Kuya Obet's own accounts (his life in Papua New Guinea) mentioned to me over bottles of beers in 2006.

My earliest memories

We grew up from a very tightly knitted family which is common to most Filipinos especially the poor ones because that is our only wealth, i.e., strong love and affection for each other.  We were born poor that in most days our meal consists mostly of rice+saluyot, on good days rice+carabao's milk + salt (my favorite) and on worse days rice + plain water + sugar. But while we lack a lot of things, we were very happy growing; abundant with love for each other that we don't care much about those.  We were physically fit and being children do not complain much.

Monday, May 19, 2014

Word Automation - Create Table, Merge Cells

I was pondering a question inside foxite forum about word automation because of the handicap presented by MS that when recording a macro in Word, objects cannot be clicked using mouse.

So the first solution that I can think of is to use keyboard as that is still allowed and that to customize Quick Access Toolbar to include an icon for merging so I can click (and merge cells) for later reviewing of macro recordings.  And this resulted to these codes:

Wednesday, May 14, 2014

3rd party apps within our forms - Detaching


Yesterday, I gave you the ways to place a 3rd party app inside our form.  Today though I thought "What if my users want to work on those excel file outside on its own after I have shown those inside my form?".  And so I decided to find a way to detach those back outside.

Tuesday, May 13, 2014

3rd party apps from within our forms


It is now 1:30am and I still can't sleep again so let us make my time a bit useful.

Inspired by what Bernard Bout has shown here, I decided to see earlier today how it can be done on an excel instance.  Please read it (click on here word above) before proceeding below as I will try to break things apart for our better understanding.

The barest tools of the Trade

Monday, May 5, 2014

More Objects in a Grid Cell - Part III

I shared last time a way to show several objects within a grid's cell and I was surprised that it landed 2nd on my top posts.  Said tutorial and sample uses 4 containers, if I can recall properly, and usage of DynamicCurrentControl.  I did that when I was still in the process of experimenting on my assets masterfile module of which I use a grid with 3 columns with each columns showing different info:

Friday, May 2, 2014

Health Benefits - Super Fruits - Part I

One constant problem that I have is hypertension.  Originally I was given 5mg amlodipine (I won't name the brand) and I constantly argued with my sister who is a head nurse and my mother.. and oh plus my wife... that it does nothing to improve my condition. But one time in December last year I got really sick when I recorded an all time score of 199/113.   Yippee!!!!  Well I sometimes get a higher Diastolic such as 130 but that is the first time my Systolic reached 199 (see http://en.wikipedia.org/wiki/Blood_pressure).  Only one worm less waiting for a pen?

Anyway, that forced me to experiment increasing my intake from that 5mg to the whole 10mg on that day.  And immediately I felt better (plus 1 hour exercise over my stationary bike to sweat out whatever it is that needs to be sweat out).  Although I do not recommend that you guys do an exercise when having an HBP.  Majority cautions against it.

Improper Dosage

Saturday, April 26, 2014

GOMONTH() on an End Of Month, Beware!!!

What is GOMONTH() Function?

GOMONTH() gives us the ability to move forward/backward on a specified number of months before or after a given Date or Date/Time expression:

Create Cursor junk (xdate d)
ldBase = Date(2014,1,1)
For lnloop = 1 To 12
      Insert Into junk Values (GOMONTH(m.ldBase,1))
      ldBase = xdate
Next
Browse Normal

I have been comfortably using GOMONTH() without any thought of its known bug which is that it returns empty dates before 09/14/1752 because I definitely won't need to go way back that far for any date requirements.

However, I expect that when I perform GOMONTH() on end of month dates, that it will return the end of months of the succeeding months as well.  A fellow Foxite member Gene Wirchenko mentioned that it does not that if dates fall between 28 to 30 (February 28 & 29 plus months that ends on 30), succeeding dates will show the same day; not the end of month.   I tested now and he is right:

Thursday, April 17, 2014

Get a list of Countries and Capitals of the World

Here is a simple snippet to get the countries of the world and its corresponding capitals, again via XMLHttpRequest. And so the result is dependent whether the source site won't change their HTML codes.

Actually, this is just a proposed answer to a member in need inside Foxite as he is looking for a way to get a list of something like this.  I surfed the net a while ago and saw a good site to extract info from and since there is a possibility that  someone out there who is not a member of the forum may need something like this, then here it is:

****************
* Get Countries & Capitals
****************

BizCore Popper

This is something I cannot easily share because its usage is dependent on how I design my ERP app... but hopefully it can give you ideas to do the same on your end.

What is BizCore Popper

Well, originally I plan to call this BizCore Messenger but then there is no originality on that.  And I wanted my apps to sort of look and feel unique.  So I changed the name into Popper (it pops up a message, isn't it?).  So there you go, BizCore Popper.

Brief History 

We actually have a messenger for our LAN here but said messenger do not run under Windows higher than XP.  So it is half used in our office.

My BizCore ERP done in VFP9 runs though on any Windows OS we have so I thought instead of relying onto a 3rd party app, why not create my own?  And then the thought got shelved somewhere in the corner of my mind and remained dormant for a very long time due to a lot other things I do.

However, one time Ony Too shared a new library with a cachy name FoxGrowl inside Foxite which is actually a desktop notification tool.  And my plan on creating a messenger has been reactivated thinking I will turn FoxGrowl into a messenger.  Though the design for FoxGrowl is to notify every one on the LAN and not a specific user, it can be turned into a selective/specific user notification.

But then, I realized I will have to change a lot on said Library to suit my needs that in the end the design will be totally different than the growling notification it is intended to be.  So I abandoned the modification of the library and instead built myself something totally different which is what this ERP is using now.  If you are intrigued on what FoxGrowl is, here is the link showing also the download link:  http://www.foxite.com/archives/0000403119.htm

Wednesday, April 9, 2014

Working on Invisible Objects

I remembered this is another trick I use on my end (mostly in connection with ssToExcel and ssExcelPivot classes) and some may not know that this can be done so here it is.

When I designed both classes, I am still working back then with ssButton series.  While I still sometimes use those, now I prefer mostly ButtonX of ssUltimate library which I started working on after I shared ssClasses in CodePlex; the purpose is to give my subscribers an edge for the monetary contributions they gave me (later I will start showing here the new classes on that new library)

Having said, ButtonX is cleaner, and has improved codes and looks than its ancestors ssButton series.  As I keep on designing buttons, switches and other things over the years on Photoshop, I believe I was able to slowly refine the new looks for those classes.  And so using ssToExcel or ssExcelPivot classes now on my forms will somewhat break the look of my recent GUI designs.

Tuesday, April 8, 2014

Extending ssToExcel & ssExcelPivot classes

For those who are familiar with ssToExcel, ssToExcel2, and ssExcelPivot classes, then they already know that it can easily export records from a table or cursor into Excel with added formats or create a pivot report by setting just a few properties in no time at all.  For those who are wondering what these classes are, then here are my original posts on this:

ssToExcel2:
http://sandstorm36.blogspot.com.au/2012/02/sstoexcel2.html

ssExcelPivot:
http://sandstorm36.blogspot.com.au/2012/12/ssexcelpivot-class-enhancements.html
http://sandstorm36.blogspot.com.au/2012/02/ssexcelpivot-class.html


Those classes are designed to be used generic as users may export different data to excel, in their own particular field ordering based on their needs.  But sometimes though, the generated output of these two classes may still lack something.  Like for instance, while I gave the ability to show total of a numeric columns like this:

      This._totalfields = 'Regular,OT,Holiday,Total'

Which will create a total on those 3 fields (vertically), I have not added a horizontal summation capability.  Why?  Because a user's exported data may vary based on the record source, the last may not be a column representing the numeric total of the fields on its left.

Is there a way to perform extra automation on the sheets generated by these classes?

Excel, Knowing the last row per sheet

Here is a very simple automation trick on how to find out the last row on an Excel Sheet.  This also shows how to find out the number of sheets, how to transfer between those, plus knowing the last row of each sheet.

Enjoy!


#Define xlLastCell 11

Local lcFile, loExcel As Excel.Application, lnLastRow, lnloop
lcFile = Getfile("xls,xlsx")
If !Empty(m.lcFile)   && check if not cancelled
      loExcel = Createobject("excel.application")
      With loExcel
            .Workbooks.Open(m.lcFile)
            For lnloop = 1 To .sheets.Count
                  .Worksheets(m.lnloop).Select
                  .ActiveCell.SpecialCells(xlLastCell).Select
                  lnLastRow = .ActiveCell.Row
                  Messagebox('Sheet'+Transform(m.lnloop)+' last Row'+;
                                     Transform(m.lnLastRow))
            Next
            * Visually Check
            .Visible = .T.
      Endwith
Else
      Messagebox("Aborted by user!",0+64,"Oppppssss!")
Endif

Saturday, April 5, 2014

Localized Data II - Animated Weather

They say a picture paints a thousand words so I will try to show here my weather forecast section and what the animation effect brings to that.

IMHO, this gives a better feel for the users of my app than the normal weather animations we see on the web or on our mobile gadgets.  Plus I always like to have something unique for my apps.

Now, for you be able to achieve the same effect, what you need to do is download animated images from the web, create a table for it, store it to a memo or blob field, and create another field to trap the weather condition which is unique with the web site you will be getting your forecast from.

Like I said with the first blog about this, what I do then on my end is refresh data every 60 seconds and display result on the section of my form for that.  Then I perform an SQL SELECT to get all animations stored on my table which has the same weather condition on the current hour forecast, and finally picks one randomly to be shown above the forecast.

Here is the section of said weather forecast for you to see.  Although the image of the grid representing the forecast is not clear here because I have to resize it larger to fit with the animated image I have shown here whereas on my app, it is the other way around.  The animated image is stretched to fit with the same size of my actual grid below.

Foolish me!  I like this animated image of raining so I chose it.  So as not to confuse the readers, I've overwritten the Cloudy weather with Heavy Rain but forgot to change the caption of Current Weather.  LOL!


And here is the portion where it randomly picks for an animated image:

* Select Animation
Use weather In 0 Shared
Use weathergrp In 0 Shared
With This.imgweather
      .Picture = ''
      * Get an animation based on Weather
      Select t1.wimage, t2.Descript From weather t1;
            LEFT Outer Join weathergrp t2;
            ON t2.wgpk = t1.wgfk;
            WHERE Alltrim(t2.Descript) == m.lcWeather ;
            Into Cursor JunkWeather NOFILTER
      If _Tally > 0
            Goto (1 + _Tally * Rand( ))
            lcImage = Addbs(Getenv("TEMP"))+'weather.gif'
            Strtofile(JunkWeather.wimage,m.lcImage)
            .Picture = m.lcImage
            .Visible = .T.
      Else
            .Visible = .F.
      Endif
      Use In Select('Weather')
      Use In Select('WeatherGrp')
Endwith
      * End of Select Animation

Its advantage is speed, being all data are localized.  You won't see it lagging as both the weather forecast info and weather animation is updated/changed in a split second .

You can achieve the same on your end, just follow the ideas I shared here and in the first part of localized data blog.  Cheers!


Friday, April 4, 2014

Localized Data

Cousin Glen shared a way to put the weather on our form in his blog as well as in foxite last time and so when I decided that I finally needed one because we are working simultaneously on several road construction projects these days and the weather forecast will be helpful, I did not need to look far away and simply checked what he has shared which is via XMLHttpRequest.

What is XMLHttpRequest?

XMLHttpRequest (XHR) is an API available to web browser scripting languages such as JavaScript. It is used to send HTTP or HTTPS requests to a web server and load the server response data back into the script.  http://en.wikipedia.org/wiki/XMLHttpRequest

Using XMLHttpRequest has some (expected) peculiarities like it appears based on my observation that the previous request is compounding seeing my laptop which is doing the data fetching getting slower over time. Thus, I informed him of such and we decided to do these additional things:

Wednesday, April 2, 2014

Combobox using RowSourceType = 3, How to update content?

Well I use this to answer inside foxite forum earlier but then I just thought maybe some does not know yet how to use a cursor from an SQL SELECT as RowSource of a combobox, or if some do, they are maybe wondering how to update such when there is a change from the source table/cursor, in result keeping them away over its usage on a combobox; so I transferred it over here as part of my simple tutorials.

You see, I prefer to work on cursors on my end as that makes my app works faster, less prone to corruption (possibility of corruption may happen only during transferring of data from cursor to actual table), and easier to maintain.

So I use cursors on grids, listbox, combobox, etc.  However, some may have been wondering that if they use a cursor for a combobox RowSource, how to update said combobox then when there is a change in data from the actual table it is coming from?  Or in other words, how to show the changes back to the combobox when it is already set to run on a cursor that was created earlier than when the change on the actual source table/cursor happened?

Monday, March 31, 2014

Highlighting Pageframe ActivePage

Aesthetics is something that always fall to individual tastes. Some wanted their app to simply follow the OS theme, others want it to look plain, yet others like me wants to make it a bit colorful or somewhat unique thinking it will spice up the app.

However, sometimes we tend to overdo the look.  For example, in the past I tend to create a pageframe with several pages each having its own colors (theme should be set to .F. otherwise the color will be ignored). In the first glance, things look cool to my taste but then in the end either I simply turn the theme back on because I get tired of the multitude of colors or I just retain one color for all pages with theme still set to .F.

Saturday, February 1, 2014

LOCATE vs SEEK, which is faster?

From time to time someone would inquire which is faster?  LOCATE or SEEK? And the answer mostly is it depends, if the records are small, then the speed difference is negligible enough.  True.  But that does not still answer which really is faster.  When we say faster, it has to be at least a nanosecond quicker than the other one.  We are not arguing "how" fast but "which" is faster.



To understand better which is really faster, we have to first understand how the two differs.  How does LOCATE performs searching?  How does SEEK performs searching?  Let us start with SEEK() first.

HOW DOES SEEK() PERFORM SEARCHING?

Thursday, January 30, 2014

Slow Connection? Sniff your way out!

This is actually mostly for IT personnel but is very useful as well for developers encountering slow connection on LAN.  Speaking as both, one thing that we face most of the time is degradation of speed on the network and the problem is it can be anything such as wrong design in our app, faulty hardware like switches and lan cards, or a malware flooding the network causing heavy traffic.

As an IT Manager, what I do on my end, for lack of proper tools before, is to trace things manually.  Sometimes with the help of IpSnooper tool I shared in foxite, weblogs and blogspot, I was able to pinpoint which machine a specific IP Address belongs to.  But that is if you will be able to trace which IP is flooding the network.

For some cases, like I said, I have to do it manually (with my IT guys' assistance) by observing the speed  of the network or even internet access by unplugging one by one (and reconnecting back) each connection on our switch.  And I was able to trace the units causing the flooding that way.  But...... that is the hard way.

Monday, January 6, 2014

Printer Environment on Report, when to save and when not to!

In earlier versions of VFP (before 9), Printer Environment is by default saved onto the report itself.  But then there are cases where because of that, when our app is installed on a client's machine and that machine has a different printer than what we have when we design the report and compiled the app into exe, the report output on the client machine may generate a much different output than what we are expecting like difference on dimensions, margins, font sizes, spaces, some portion cut-off, etc.  And the solution to those problems is to hack into the FRX and clear out these printer environment from within so it will be free of the settings of a "specific" printer.

For these reasons, in VFP9, VFP team saw the need to reverse the process by not saving printer environment anymore within the report.  They made it optional by adding a checkbox in Page Setup of a report that allows us to save or not printer environment.  And by reverse, I mean the default now is it is no longer saved.

Question is, if saving printer environment results to unwanted outputs that has often led developers in lower versions of VFP to always hack the frx files, why should we tick it then?  Why is this option still given to us?  Why not simply remove this feature?  Is there still any use for this?