shell thingy

General FreeBASIC programming questions.
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

shell thingy

Postby cha0s » Oct 27, 2005 4:18

hi, i was working on my shell thingy and i realized that whenever i invoke a cmd prompt, the prog halts until i close that command prompt.

so i remembered people talking about threads; check the example and implemented it myself. however, i found that the 'Shell "command"' was still halting even the threads returning until it was closed.

i then tested the thread program using "explorer." it sucessfully opened each explorer window in a different thread.

the reason i fgured out it halts is because in the code there is a thing to make a window always on top.

well, here's the code... my question is... is it possible to open a command prompt in a concurrently running thread? or am i doomed to wait for it to 'finish', always..

NOTE: due to the nature of this program, it is recommended to only compile and run it using the "-s gui" switch through fbc.exe.

also, this code will probably only compile in .14 without tweaking the win calls. (and, i've edited my local user32.bi to accomodate default function params :p)



Code: Select all

#Include "win\user32.bi"
#Include "fbgfx.bi"

Declare Sub cmd( ByVal num As Integer)

Declare Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
Declare Function GetAllWindows() As Integer

Screen 13


ReDim Shared WinHandle(1 To 1) As Long
Dim Shared WinHandleCount As Long
Dim Shared lWindows(1 To 1) As Long
Dim Counter As Long
Dim sWindows As String
Dim WinTitle As String
Dim TitleLen As Long

Dim prompts As uInteger



Dim As Double _timer, s_timer, e_timer
Dim As Integer hwnd


WindowTitle "Shl"

hwnd =  FindWindow( 0, "Shl" )

ShowWindow ByVal hwnd, sw_hide


Dim As Integer a, switch = Not 0

ReDim Shared As uInteger cmd_cnt(0)


ThreadCreate( @cmd, prompts )
prompts = 1


Do

  a = GetForegroundWindow



  If MultiKey( sc_control ) And MultiKey( sc_alt ) Then
 
 
    If _timer = 0 Then
   
      _timer = Timer + 1
     
    End If
   
    If Timer >= _timer Then
   
      cmd_cnt( prompts ) = ThreadCreate( @cmd, prompts )
      _timer = 0
     
    End If
 
  Else
 
    _timer = 0
   
  End If


  If MultiKey( sc_control ) And Not MultiKey( sc_alt ) Then
 
 
    If s_timer = 0 Then
   
      s_timer = Timer + 1
     
    End If
   
    If Timer >= s_timer Then

      switch = Not switch
     
      MessageBeep
     
     
      SetWindowPos( a, switch - 1, , , , , swp_nomove Or swp_nosize )



      For flsh = 0 To 3
       
        Dim As Double b_timer
       
        b_timer = Timer + .3 - ( ( flsh  * 4 ) / 100 )
       
        FlashWindow( a, -1 )

        Do
       
          Sleep 1
                                 
        Loop While Timer < b_timer
 
 
                                 
       
      Next
     
     
     
       
      s_timer = 0
     
    End If
   
 
  Else
 
    s_timer = 0
   
  End If


  If MultiKey( sc_escape ) And Not MultiKey( sc_control ) Then
 
    If e_timer = 0 Then
   
      e_timer = Timer + 1
     
    End If
   
    If Timer >= e_timer Then
   
      End
     
    End If
 
  Else
 
    e_timer = 0
   
  End If
   


  WinHandleCount = 0
  prompts = 0
 
 
  If GetAllWindows() = True Then
 
    If WinHandleCount > 0 Then
 
      For Counter = 1 To WinHandleCount
 
 
        'Get the length of the buffer we need
        TitleLen = GetWindowTextLength(WinHandle(Counter)) + 1
 
        'Create the buffer
        WinTitle = Space$(TitleLen + 1)
        GetWindowText(WinHandle(Counter), WinTitle, TitleLen + 1)
        WinTitle = Trim$(WinTitle)
        DestroyWindow (WinHandle(Counter))
 
        If Left( WinTitle, 13 ) = "MS-DOS Prompt" Then prompts += 1

       
        ReDim Preserve cmd_cnt( prompts - 1 )

'        ? WinTitle                           
        WinTitle = ""
 
           
      Next
 
    End If
 
  End If
 
  Erase WinHandle

  Sleep 2


Loop


Sub cmd( ByVal num As Integer)
     

      Shell "c:\windows\command.com"
     
End Sub





'Here is the callback function that returns each window handle
Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
  'Inc the array index
  WinHandleCount = WinHandleCount + 1
  ReDim Preserve WinHandle(1 To WinHandleCount) As Long
  ' Add the information to the array
  WinHandle(WinHandleCount) = hWnd
  ' Tell the function to keep going
  EnumWindowsProc = 1
End Function

Function GetAllWindows() As Integer
  ' Start enumerating through the windows
  'The @ passes the address of EnumWindowsProc
  If EnumWindows(@EnumWindowsProc, 0) <> 0 Then
    GetAllWindows = True
  End If
End Function


the window enumeration routine was taken from some posted source of either Jerry Fielden, or fsw, to be honest i can't remember, but those are the local win32 gurus ;p
yetifoot
Posts: 1710
Joined: Sep 11, 2005 7:08
Location: England
Contact:

Postby yetifoot » Oct 27, 2005 6:58

Have a look into CreateThread and CreateProcess, Also AllocConsole may be something you want.
Jerry Fielden
Posts: 165
Joined: May 27, 2005 14:14
Location: Marshall, Oklahoma, USA
Contact:

Postby Jerry Fielden » Oct 27, 2005 13:05

As much as I would like to be labeled as a GURU, but I'm afraid you got it wrong. There's many here that has a higher degree of knowledge of the Windows API then I do or ever will have.

Thanks anyway.

Later..........Jerry Fielden
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Oct 27, 2005 21:10

i couldnt figure out how to get any of those options up and running. and alloc console is just what i would gte if i didn't use -s gui...

:( can anyone tell me why command.com stops execution of the thread but nothing else does..?
yetifoot
Posts: 1710
Joined: Sep 11, 2005 7:08
Location: England
Contact:

Postby yetifoot » Oct 27, 2005 22:33

I couldnt get your example to run but heres a basic thing i knocked up, i hope its what you want

Code: Select all

#Include "windows.bi"

Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As HWND, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

ShellExecute(HWND_DESKTOP,"open","command.com","","",SW_SHOW)

MessageBox(HWND_DESKTOP,"Test","Hello",MB_OK)


This will open command.com and before it is closed will give a messagebox, it avoids the need for a thread.

Heres the info on the function, i ripped it from Paul Kuliniewicz's VB API Guide

ShellExecute Function

Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long

Platforms

* Windows 95: Supported.
* Windows 98: Supported.
* Windows NT: Requires Windows NT 3.1 or later.
* Windows 2000: Supported.
* Windows CE: Not Supported.

Description & Usage

ShellExecute opens, prints, or executes a file using the Windows shell. When working with a non-executable file, the file is opened using its associated program. ShellExecute can also open Windows Explorer windows. The function returns immediately after opening the file, starting the program, or performing whatever other action was specified.
Return Value

If successful, the function returns a handle to the instance of the application which the function started. If an error occured, the function returns either 0 (indicating a lack of memory) or one of the following flags:

ERROR_BAD_FORMAT
The specified executable file was somehow invalid.
SE_ERR_ACCESSDENIED
Access was denied.
SE_ERR_ASSOCINCOMPLETE
The filename association is either incomplete or invalid.
SE_ERR_DDEBUSY
The DDE action could not run because other DDE actions are in process.
SE_ERR_DDEFAIL
The DDE transaction failed.
SE_ERR_DDETIMEOUT
The DDE transaction was not completed because the request timed out.
SE_ERR_DLLNOTFOUND
A required DLL file could not be found.
SE_ERR_FNF
The file could not be found.
SE_ERR_NOASSOC
There is no program associated with the specified type of file.
SE_ERR_OOM
Windows has insufficient memory to perform the operation.
SE_ERR_PNF
The path could not be found.
SE_ERR_SHARE
A sharing violation occured.

Visual Basic-Specific Issues

None.

Parameters

hwnd

A handle to the window calling the function.

lpOperation

The operation to perform on lpFile. This can be one of the following strings, although other options are possible, depending on the file being acted upon:

"explore"
If lpFile is a path name, open it in a Windows Explorer window.
"open"
Open lpFile using its associated program. Opening an executable file runs it. This is the default action if none is specified.
"print"
Print lpFile using its associated program.

lpFile

The name of the file to open, print, execute, or whatever is specified by lpVerb.

lpParameters

Additional parameters to use to perform the action. This would typically be additional command-line options to use, especially when running an executable file.

lpDirectory

The path name of the working directory to use. If this is not specified, the current directory is used.

nShow

One of the following flags specifying how to display any window that might be opened:

SW_HIDE
Hide the opened window.
SW_MAXIMIZE
Maximize the opened window.
SW_MINIMIZE
Minimize the opened window.
SW_RESTORE
Restore the opened window (not maximized nor minimized).
SW_SHOW
Show the opened window.
SW_SHOWMAXIMIZED
Show the opened window maximized.
SW_SHOWMINIMIZED
Show the opened window minimized.
SW_SHOWMINNOACTIVE
Show the opened window minimized but do not activate the it.
SW_SHOWNA
Show the opened window in its current state but do not activate it.
SW_SHOWNOACTIVATE
Show the opened window in its most recent size and position but do not activate it.
SW_SHOWNORMAL
Show the opened window and activate it (as usual).

Constant Definitions

Const ERROR_BAD_FORMAT = 11
Const SE_ERR_ACCESSDENIED = 5
Const SE_ERR_ASSOCINCOMPLETE = 27
Const SE_ERR_DDEBUSY = 30
Const SE_ERR_DDEFAIL = 29
Const SE_ERR_DDETIMEOUT = 28
Const SE_ERR_DLLNOTFOUND = 32
Const SE_ERR_FNF = 2
Const SE_ERR_NOASSOC = 31
Const SE_ERR_OOM = 8
Const SE_ERR_PNF = 3
Const SE_ERR_SHARE = 26
Const SW_HIDE = 0
Const SW_MAXIMIZE = 3
Const SW_MINIMIZE = 6
Const SW_RESTORE = 9
Const SW_SHOW = 5
Const SW_SHOWMAXIMIZED = 3
Const SW_SHOWMINIMIZED = 2
Const SW_SHOWMINNOACTIVE = 7
Const SW_SHOWNA = 8
Const SW_SHOWNOACTIVATE = 4
Const SW_SHOWNORMAL = 1
Last edited by yetifoot on Mar 25, 2006 21:09, edited 1 time in total.
cha0s
Site Admin
Posts: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Oct 28, 2005 4:03

yes, this returns instantly, just what i need. thanks a lot for your fast, informative reply!

Return to “General”

Who is online

Users browsing this forum: Bing [Bot] and 3 guests