Welcome to SPN

Register and Join the most happening forum of Sikh community & intellectuals from around the world.

Sign Up Now!

Automation Issues

Discussion in 'Information Technology' started by jason.vanbrackel@gmail.com, Jul 28, 2006.

  1. jason.vanbrackel@gmail.com

    jason.vanbrackel@gmail.com
    Expand Collapse
    Guest

    I have a VB6 Application that shells out some activity to another VB6
    application in a separate thread. This second application relies
    heavily upon the Microsoft Access 10.0 Object Library. I have also
    used the Microsoft Access 11.0 Object Library. This second application
    grabs recordsets from the Access mdb by using the below set of
    commands.

    Set qdfX = objAccess.CurrentDb.CreateQueryDef("", strSQLX)
    Set rstX = qdfX.OpenRecordset()

    I did not write this and I personally find this method of grabbing data
    from Access to be a rather poor design choice, but it is entrenched
    within the application, and it is unlikely that I can change it at this
    point.

    I believe the use of the automation in this manner may be causing the
    application to freeze on some machines. It causes it and its parent
    application to freeze as well. The rest of the machine continues to
    run normally, and I have to kill the processes in Task Manager.

    The second app is started from the first application with the code
    below

    ExecCmdLineEx """" & gstrDataManagerPath & "\" & DATA_MANAGER_EXE & """
    -e[i2] -a[1]", SW_SHOWMINNOACTIVE, ABOVE_NORMAL_PRIORITY_CLASS

    ----ExecCmdLineEx Module----

    Option Explicit

    Private Type STARTUPINFO
    cb As Long
    lpReserved As String
    lpDesktop As String
    lpTitle As String
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
    End Type

    Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessID As Long
    dwThreadID As Long
    End Type

    Private Declare Function WaitForSingleObject _
    Lib "kernel32" ( _
    ByVal hHandle As Long, _
    ByVal dwMilliseconds As Long
    _
    ) As Long

    Private Declare Function CreateProcessA _
    Lib "kernel32" ( _
    ByVal lpApplicationName As
    String, _
    ByVal lpCommandLine As
    String, _
    ByVal lpProcessAttributes As
    Long, _
    ByVal lpThreadAttributes As
    Long, _
    ByVal bInheritHandles As
    Long, _
    ByVal dwCreationFlags As
    Long, _
    ByVal lpEnvironment As Long,
    _
    ByVal lpCurrentDirectory As
    String, _
    lpStartupInfo As STARTUPINFO,
    _
    lpProcessInformation As
    PROCESS_INFORMATION _
    ) As Long

    Private Declare Function CloseHandle _
    Lib "kernel32" ( _
    ByVal hObject As Long _
    ) As Long
    Private Declare Function GetExitCodeProcess _
    Lib "kernel32" ( _
    ByVal hProcess As Long, _
    lpExitCode As Long _
    ) As Long


    Private Const INFINITE = -1&

    'Show Window Constants
    Private Const SW_HIDE = 0
    Private Const SW_SHOWNORMAL = 1
    Private Const SW_SHOWMINIMIZED = 2
    Private Const SW_MAXIMIZE = 3
    Private Const SW_SHOWMAXIMIZED = 3
    Private Const SW_SHOWNOACTIVATE = 4
    Private Const SW_SHOW = 5
    Private Const SW_MINIMIZE = 6
    Private Const SW_SHOWMINNOACTIVE = 7
    Private Const SW_SHOWNA = 8
    Private Const SW_RESTORE = 9
    Private Const SW_SHOWDEFAULT = 10
    'End Show Window Constants

    'Priority Class Constants
    Private Const REALTIME_PRIORITY_CLASS = &H100&
    Private Const HIGH_PRIORITY_CLASS = &H80&
    Private Const ABOVE_NORMAL_PRIORITY_CLASS = &H8000&
    Private Const NORMAL_PRIORITY_CLASS = &H20&
    Private Const BELOW_NORMAL_PRIORITY_CLASS = &H4000&
    Private Const IDLE_PRIORITY_CLASS = &H40&
    'End Priority Class Constants

    Public Function ExecCmdLineEx( _
    szCommandLine, _
    Optional nCmdShow As Variant, _
    Optional dwPriorityCreationFlags As
    Variant _
    ) As Long

    Dim proc As PROCESS_INFORMATION
    Dim start As STARTUPINFO
    Dim lngReturnCode As Long

    Const STARTF_USESHOWWINDOW = &H1

    ' Initialize the STARTUPINFO structure:
    With start
    .cb = Len(start)

    'If this is missing then wShowWindow is ignored
    .dwFlags = STARTF_USESHOWWINDOW
    If (IsNull(nCmdShow)) Then
    .wShowWindow = SW_SHOW
    Else
    .wShowWindow = nCmdShow
    End If

    End With

    ' Start the shelled application:

    If IsNull(dwPriorityCreationFlags) Then
    lngReturnCode = CreateProcessA(vbNullString, _
    szCommandLine, _
    0&, _
    0&, _
    1&, _
    NORMAL_PRIORITY_CLASS, _
    0&, _
    vbNullString, _
    start, _
    proc _
    )
    Else
    lngReturnCode = CreateProcessA(vbNullString, _
    szCommandLine, _
    0&, _
    0&, _
    1&, _
    dwPriorityCreationFlags, _
    0&, _
    vbNullString, _
    start, _
    proc _
    )
    End If

    ' Wait for the shelled application to finish:
    lngReturnCode = WaitForSingleObject(proc.hProcess, INFINITE)
    Call GetExitCodeProcess(proc.hProcess, lngReturnCode)
    Call CloseHandle(proc.hThread)
    Call CloseHandle(proc.hProcess)

    ExecCmdLineEx = lngReturnCode

    End Function

    Any Ideas?
     
  2. Loading...

    Similar Threads Forum Date
    Kicking Marketing Automation into High Gear (NewsFactor) Interfaith Dialogues Mar 29, 2005
    India AAP hijacks SAD's traditional Sikh issues Breaking News Mar 29, 2014
    Vital Issues pertaining to Sikh Youth Sikh Youth Jan 26, 2014
    World Emirates issues clarification after Sikh pilot alleges discrimination Breaking News Nov 7, 2013
    UK UK Sikh Council Raise Issues of Sikh Identity with Akal Takht Jathedar Breaking News Oct 1, 2013

  3. dbahooker@hotmail.com

    dbahooker@hotmail.com
    Expand Collapse
    Guest

    yeah my idea is:

    a) wake up to the 90s and dont use DAO for anything
    b) wake up to the 90s and dont use MDB for anything
    c) wake up to the 90s and dont use Vb6 for anything.

    Access Data Projects are AWESOME!!
     
  4. J French

    J French
    Expand Collapse
    Guest

    On 17 May 2006 07:14:51 -0700, jason.vanbrackel@gmail.com wrote:

    <snip>

    > ' Wait for the shelled application to finish:
    > lngReturnCode = WaitForSingleObject(proc.hProcess, INFINITE)


    Don't do an infinite wait
    - don't wait, use DoEvents to keep your first App alive

    'Wait
    Do
    WaitMessage ' JF
    Me.Print ".";
    Count = Count + 1
    If Count > 100 Then
    Count = 0
    Me.Cls
    End If
    DoEvents
    Loop While WaitForSingleObject(pinfo.hProcess, 0)

    > Call GetExitCodeProcess(proc.hProcess, lngReturnCode)
    > Call CloseHandle(proc.hThread)
    > Call CloseHandle(proc.hProcess)
    >
    > ExecCmdLineEx = lngReturnCode
    >
    >End Function
    >
    >Any Ideas?
    >
     
  5. Anthony Jones

    Anthony Jones
    Expand Collapse
    Guest

    "J French" <erewhon@nowhere.uk> wrote in message
    news:446c5e4e.260881772@news.btopenworld.com...
    > On 17 May 2006 07:14:51 -0700, jason.vanbrackel@gmail.com wrote:
    >
    > <snip>
    >
    > > ' Wait for the shelled application to finish:
    > > lngReturnCode = WaitForSingleObject(proc.hProcess, INFINITE)

    >
    > Don't do an infinite wait
    > - don't wait, use DoEvents to keep your first App alive
    >
    > 'Wait
    > Do
    > WaitMessage ' JF
    > Me.Print ".";
    > Count = Count + 1
    > If Count > 100 Then
    > Count = 0
    > Me.Cls
    > End If
    > DoEvents
    > Loop While WaitForSingleObject(pinfo.hProcess, 0)
    >


    This will make this code highly computable while it actually does nothing.
    It makes the app responsive to user events which may be a good thing.
    OTH the rest of the code in the app needs to take care not to interfere with
    this unfinished business or use information from this activity until it's
    finished.

    Those dots on the screen will becoming thick and fast too.

    A small time out of say 500ms might be worth introducing.

    If the created process is hung then this look never exits so an additional
    counter might be needed to terminate the loop after certain period has
    elapsed.



    > > Call GetExitCodeProcess(proc.hProcess, lngReturnCode)
    > > Call CloseHandle(proc.hThread)
    > > Call CloseHandle(proc.hProcess)
    > >
    > > ExecCmdLineEx = lngReturnCode
    > >
    > >End Function
    > >
    > >Any Ideas?
    > >

    >
     
  6. J French

    J French
    Expand Collapse
    Guest

    On Sat, 20 May 2006 12:45:35 +0100, "Anthony Jones"
    <Ant@yadayadayada.com> wrote:

    <snip>

    >This will make this code highly computable while it actually does nothing.


    No, it will make the App do nothing until there is a Message in the
    Apps Windows Message Queue

    WaitMessage releases everything to Windows until a Message comes in,
    then it returns immediately

    I'm assuming that :
    WaitForSingleObject(pinfo.hProcess, 0)
    generates a WindowsMessage, or more specifically that a closing App
    generates one.

    >It makes the app responsive to user events which may be a good thing.


    Sure is

    >OTH the rest of the code in the app needs to take care not to interfere with
    >this unfinished business or use information from this activity until it's
    >finished.


    Better that, than have a totally frozen App that cannot even re-paint
    itself

    >Those dots on the screen will becoming thick and fast too.


    Not if they are Remmed out
    - they are only there in the example to give a visual indication of
    what is going on

    >A small time out of say 500ms might be worth introducing.


    Why bother ?
    If a message needs processing, then process it

    >If the created process is hung then this look never exits so an additional
    >counter might be needed to terminate the loop after certain period has
    >elapsed.


    You are right about that, but that was not the question

    If you want to do that then activate a normal VB Timer with a interval
    of say 1 sec to act as a Message pump

    That way the App will get at least 1 msg per sec, and the code in the
    loop can decide when to cop out.

    You need to have a serious look at what WaitMessage does, it is a
    fascinating beast
    - and extremely efficient at keeping down unnecessary processing

    It can be used for all sorts of tasks, my favourite is for totally
    hijacking the Windows loop
     
  7. Anthony Jones

    Anthony Jones
    Expand Collapse
    Guest

    "J French" <erewhon@nowhere.uk> wrote in message
    news:44700b80.501864146@news.btopenworld.com...
    > On Sat, 20 May 2006 12:45:35 +0100, "Anthony Jones"
    > <Ant@yadayadayada.com> wrote:
    >
    > <snip>
    >
    > >This will make this code highly computable while it actually does

    nothing.
    >
    > No, it will make the App do nothing until there is a Message in the
    > Apps Windows Message Queue
    >
    > WaitMessage releases everything to Windows until a Message comes in,
    > then it returns immediately
    >
    > I'm assuming that :
    > WaitForSingleObject(pinfo.hProcess, 0)
    > generates a WindowsMessage, or more specifically that a closing App
    > generates one.
    >


    Oops I didn't spot that WaitMessage function. It might be useful to the OP
    to provide it's declare (simple though it might be I didn't spot it and it's
    not obvious its an API call):-

    Private Declare Function WaitMessage Lib "user32" () As Long

    However I can't see how the termination of the launched process would
    generate a windows message to cause waitmessage to return.

    > >It makes the app responsive to user events which may be a good thing.

    >
    > Sure is
    >
    > >OTH the rest of the code in the app needs to take care not to interfere

    with
    > >this unfinished business or use information from this activity until it's
    > >finished.

    >
    > Better that, than have a totally frozen App that cannot even re-paint
    > itself
    >


    Agreed but there is more work that needs to be done and I still don't think
    a DoEvents loop is the approach to take.

    > >Those dots on the screen will becoming thick and fast too.

    >
    > Not if they are Remmed out
    > - they are only there in the example to give a visual indication of
    > what is going on


    They would in fact be a little random since they depend on messages
    arriving.

    >
    > >A small time out of say 500ms might be worth introducing.

    >
    > Why bother ?
    > If a message needs processing, then process it


    That statement was made without the WaitMessage function being spotted.

    >
    > >If the created process is hung then this look never exits so an

    additional
    > >counter might be needed to terminate the loop after certain period has
    > >elapsed.

    >
    > You are right about that, but that was not the question
    >


    Yes the OP wasn't interested in any of this. It's a little ambiguous but
    appears the OP seems to be wondering whether launching the process in this
    manner may be the reason it is freezing (the called process). A secondary
    affect being that the calling process freezes.

    The answer is I doubt this manner of launching the process is causing it to
    freeze but it's difficult to tell.

    > If you want to do that then activate a normal VB Timer with a interval
    > of say 1 sec to act as a Message pump
    >
    > That way the App will get at least 1 msg per sec, and the code in the
    > loop can decide when to cop out.
    >
    > You need to have a serious look at what WaitMessage does, it is a
    > fascinating beast
    > - and extremely efficient at keeping down unnecessary processing
    >
    > It can be used for all sorts of tasks, my favourite is for totally
    > hijacking the Windows loop


    I think in this case a better design would be to launch the app but not loop
    at all.

    Use a timer to check whether the process handle has been signalled.

    Modify the parent app to ensure invalid actions are not taken whilst this
    secondary process is operating.

    TBH I've never come across a problem that might be solved using a DoEvents
    loop that couldn't be better solved without one. Especially if the
    developer is happy dipping into the windows API.
     
  8. J French

    J French
    Expand Collapse
    Guest

    On Sun, 21 May 2006 08:54:09 +0100, "Anthony Jones"
    <Ant@yadayadayada.com> wrote:


    <snip>

    >Oops I didn't spot that WaitMessage function. It might be useful to the OP
    >to provide it's declare (simple though it might be I didn't spot it and it's
    >not obvious its an API call):-


    >Private Declare Function WaitMessage Lib "user32" () As Long


    Since the original post was a jiggered form of Shell And Wait from the
    KPD All API Guide, I figured that the OP would realize that
    WaitMessage is an API

    >However I can't see how the termination of the launched process would
    >generate a windows message to cause waitmessage to return.


    It seems it does
    - when an App unloads it creates a bundle of activity within Windows
    - also Windows knows very well which thread launched the App
    - I just found that it is reliable

    >> >It makes the app responsive to user events which may be a good thing.

    >>
    >> Sure is
    >>
    >> >OTH the rest of the code in the app needs to take care not to interfere

    >with
    >> >this unfinished business or use information from this activity until it's
    >> >finished.

    >>
    >> Better that, than have a totally frozen App that cannot even re-paint
    >> itself


    >Agreed but there is more work that needs to be done and I still don't think
    >a DoEvents loop is the approach to take.


    Why not ?
    a) it is not hammering the processor
    b) it is not 'blocking' the App

    Anyway an App's Window Message queue is just a loop using a variation
    of WaitMessage

    // Start the message loop.

    while (GetMessage(&msg, (HWND) NULL, 0, 0))

    {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }

    >> >Those dots on the screen will becoming thick and fast too.


    >> Not if they are Remmed out
    >> - they are only there in the example to give a visual indication of
    >> what is going on


    >They would in fact be a little random since they depend on messages
    >arriving.


    Less random than you would expect
    - they go bananas when you move the mouse, but otherwise there are
    very few of them

    >>
    >> >A small time out of say 500ms might be worth introducing.

    >>
    >> Why bother ?
    >> If a message needs processing, then process it


    >That statement was made without the WaitMessage function being spotted.



    >> >If the created process is hung then this look never exits so an

    >additional
    >> >counter might be needed to terminate the loop after certain period has
    >> >elapsed.

    >>
    >> You are right about that, but that was not the question


    >Yes the OP wasn't interested in any of this. It's a little ambiguous but
    >appears the OP seems to be wondering whether launching the process in this
    >manner may be the reason it is freezing (the called process). A secondary
    >affect being that the calling process freezes.


    <quote>
    I believe the use of the automation in this manner may be causing the
    application to freeze on some machines. It causes it and its parent
    application to freeze as well.
    </quote>

    The code is deliberately freezing the Calling App until the Called App
    returns
    - it has nothing to do with the Called App, once that is running the
    calling App has no influence

    >The answer is I doubt this manner of launching the process is causing it to
    >freeze but it's difficult to tell.


    It is definitely freezing the Caller
    - which is pretty darn silly for a 3+ minute process

    >> If you want to do that then activate a normal VB Timer with a interval
    >> of say 1 sec to act as a Message pump


    >> That way the App will get at least 1 msg per sec, and the code in the
    >> loop can decide when to cop out.


    >> You need to have a serious look at what WaitMessage does, it is a
    >> fascinating beast
    >> - and extremely efficient at keeping down unnecessary processing


    >> It can be used for all sorts of tasks, my favourite is for totally
    >> hijacking the Windows loop


    >I think in this case a better design would be to launch the app but not loop
    >at all.


    There are two types of Looping
    a) inefficient looping
    -using pure DoEvents that raises CPU usage to 100%
    b) efficient looping that responds immediately to Windows

    >Use a timer to check whether the process handle has been signalled.


    That is a possibility
    - in this case I would use an AX Exe and run the process off its
    internal thread
    - or use a normal Exe and set up a communications system

    Sometimes Waiting is sensible
    - especially if there is not much you can do until the thing comes
    back with a result

    >Modify the parent app to ensure invalid actions are not taken whilst this
    >secondary process is operating.


    Dead easy, a Modal Form with an Abort button

    >TBH I've never come across a problem that might be solved using a DoEvents
    >loop that couldn't be better solved without one. Especially if the
    >developer is happy dipping into the windows API.


    I am trying to explain to you that

    While Something
    WaitMessage
    DoEvents
    Wend

    Is NOT a DoEvents Loop
    - it is the equivalent of popping up a Modal Form ( and you can be
    sure that is how Modal Forms work )

    As I said before, you would be wise to look into the implications of
    WaitMessage
    - a lot of VB programmers don't understand it
     
  9. Anthony Jones

    Anthony Jones
    Expand Collapse
    Guest

    "J French" <erewhon@nowhere.uk> wrote in message
    news:447058da.2509737@news.btopenworld.com...
    > On Sun, 21 May 2006 08:54:09 +0100, "Anthony Jones"
    > <Ant@yadayadayada.com> wrote:
    >
    >
    > <snip>
    >
    > >Oops I didn't spot that WaitMessage function. It might be useful to the

    OP
    > >to provide it's declare (simple though it might be I didn't spot it and

    it's
    > >not obvious its an API call):-

    >
    > >Private Declare Function WaitMessage Lib "user32" () As Long

    >
    > Since the original post was a jiggered form of Shell And Wait from the
    > KPD All API Guide, I figured that the OP would realize that
    > WaitMessage is an API
    >
    > >However I can't see how the termination of the launched process would
    > >generate a windows message to cause waitmessage to return.

    >
    > It seems it does
    > - when an App unloads it creates a bundle of activity within Windows
    > - also Windows knows very well which thread launched the App
    > - I just found that it is reliable
    >


    Hmm.. seems a bit wolly. You may be right. As a process tears itself down
    it may remember what thread launched it. It may look for a window message
    pump queue thingy on that thread (does every thread in windows have on
    these? I don't think so). It may decide to put a message in that queue to
    the effect that 'a process you created is now finished'.

    It would be nice know for sure that that is what is happening. At the
    moment I think it's more likely that is works simply because some messages
    will be passing through anyway.


    > >> >It makes the app responsive to user events which may be a good thing.
    > >>
    > >> Sure is
    > >>
    > >> >OTH the rest of the code in the app needs to take care not to

    interfere
    > >with
    > >> >this unfinished business or use information from this activity until

    it's
    > >> >finished.
    > >>
    > >> Better that, than have a totally frozen App that cannot even re-paint
    > >> itself

    >
    > >Agreed but there is more work that needs to be done and I still don't

    think
    > >a DoEvents loop is the approach to take.

    >
    > Why not ?
    > a) it is not hammering the processor
    > b) it is not 'blocking' the App
    >


    How many of these loops would you want in your app? What if the process you
    launched never dies, does this loop stay inplace.


    > Anyway an App's Window Message queue is just a loop using a variation
    > of WaitMessage
    >
    > // Start the message loop.
    >
    > while (GetMessage(&msg, (HWND) NULL, 0, 0))
    >
    > {
    > TranslateMessage(&msg);
    > DispatchMessage(&msg);
    > }
    >


    Yeah but one of these is already there do we want to create others also?

    >
    >
    > >> >If the created process is hung then this look never exits so an

    > >additional
    > >> >counter might be needed to terminate the loop after certain period has
    > >> >elapsed.
    > >>
    > >> You are right about that, but that was not the question

    >
    > >Yes the OP wasn't interested in any of this. It's a little ambiguous but
    > >appears the OP seems to be wondering whether launching the process in

    this
    > >manner may be the reason it is freezing (the called process). A

    secondary
    > >affect being that the calling process freezes.

    >
    > <quote>
    > I believe the use of the automation in this manner may be causing the
    > application to freeze on some machines. It causes it and its parent
    > application to freeze as well.
    > </quote>
    >
    > The code is deliberately freezing the Calling App until the Called App
    > returns
    > - it has nothing to do with the Called App, once that is running the
    > calling App has no influence
    >
    > >The answer is I doubt this manner of launching the process is causing it

    to
    > >freeze but it's difficult to tell.

    >
    > It is definitely freezing the Caller
    > - which is pretty darn silly for a 3+ minute process
    >


    Perhaps I've read the question wrong.

    > >> If you want to do that then activate a normal VB Timer with a interval
    > >> of say 1 sec to act as a Message pump

    >
    > >> That way the App will get at least 1 msg per sec, and the code in the
    > >> loop can decide when to cop out.

    >
    > >> You need to have a serious look at what WaitMessage does, it is a
    > >> fascinating beast
    > >> - and extremely efficient at keeping down unnecessary processing

    >
    > >> It can be used for all sorts of tasks, my favourite is for totally
    > >> hijacking the Windows loop

    >
    > >I think in this case a better design would be to launch the app but not

    loop
    > >at all.

    >
    > There are two types of Looping
    > a) inefficient looping
    > -using pure DoEvents that raises CPU usage to 100%
    > b) efficient looping that responds immediately to Windows
    >

    c) Don't bother

    > >Use a timer to check whether the process handle has been signalled.

    >
    > That is a possibility
    > - in this case I would use an AX Exe and run the process off its
    > internal thread
    > - or use a normal Exe and set up a communications system
    >
    > Sometimes Waiting is sensible
    > - especially if there is not much you can do until the thing comes
    > back with a result
    >


    Agreed

    > >Modify the parent app to ensure invalid actions are not taken whilst this
    > >secondary process is operating.

    >
    > Dead easy, a Modal Form with an Abort button
    >


    Ah now it makes sense. Your WaitMessage/DoEvents loop coupled with this
    should work nicely.

    > >TBH I've never come across a problem that might be solved using a

    DoEvents
    > >loop that couldn't be better solved without one. Especially if the
    > >developer is happy dipping into the windows API.

    >
    > I am trying to explain to you that
    >
    > While Something
    > WaitMessage
    > DoEvents
    > Wend
    >
    > Is NOT a DoEvents Loop
    > - it is the equivalent of popping up a Modal Form ( and you can be
    > sure that is how Modal Forms work )
    >
    > As I said before, you would be wise to look into the implications of
    > WaitMessage


    Doesn't look like I need to. What else is there to learn that you haven't
    already explained :)

    > - a lot of VB programmers don't understand it


    I think it's more like never heard of it. I hadn't and I've been doing VB
    for more years than I care to admit. (although not a great deal of UI
    work).
     
  10. J French

    J French
    Expand Collapse
    Guest

    On Sun, 21 May 2006 14:29:50 +0100, "Anthony Jones"
    <Ant@yadayadayada.com> wrote:

    I see that you are a Dori Previn Fan
    - I went to school with her daughter

    Yada Yada is a great track - it even gets me, and I am a-musical

    On the subject, Windows is a deliberate illusion

    Mostly, I like to explain things to those that should know

    - you will probably want to know, it took me time to understand

    Right now I am inebreiated - tomorrow I shall spell ( as in spell )
    - and like most of us, show the devious paths

    Just look into WaitMessage or do a Google search
    - it is rather interesting
     

Share This Page