(Tagged messages in GFA Basic)

#: 0 S0/Header Messages  (CIS:WINAPC)
    19-Sep-96  11:10:30
Sb: Session Header Message
Fm: OzWin
To: Friedrich Rode 100602,702
Replies:   0

Welcome to Windows 3rd Party C Forum! (CIS:WINAPC)
Friedrich Rode 100602,702

Last visit: 18-Sep-96 20:14:24
Forum messages:   88186 to   93793
Last message you've read:    93772


#: 97126 S12/GFA  (CIS:WINAPC)
    17-Feb-97  23:08:23
Sb: #97106-BMP in Res file
Fm: James V. Schumacher 104166,2104
To: Dale Bryant 73134,1500 (X)
Replies:   0

>> By the way could you give me an example of loading and displaying a bitmap for a .RES file. <<

Dale,

The following code loads a bitmap called RESBIT from resources.  The bitmap resource is stored in file APP.DLL.  I create  APP.DLL by importing the bitmap into a .RES file using Borland's Resource Workshop then compiling it into a DLL using GFABasic.  

The code first gets a handle to the bitmap, then converts it from device independent format (DIB) to device dependent format.  It uses Sjouke's BMP.DLL routines DIBTOBMP and FREEBMP.

  gAppPath$ = CHR$(_DRIVE) + ":" + DIR$(0)    //path to folder containing application
  ResFilePath$ = gAppPath$ + "\APP.DLL" + CHR$(0)
  hAPPInst& = _INSTANCE
  '$LNK RES "APP.DLL"   //uncomment during compile
  hAPPInst& = LoadLibrary(ResFilePath$) //comment during compile
    hrsc& = FindResource(hAPPInst&,"RESBIT",RT_BITMAP)
    hpicture& = LoadResource(hAPPInst&,hrsc&)
    picture% = LockResource(hpicture&)
    'in DIB form ... must convert to DDB form
    IF hpicture&                    // Load OK?
      hDDB% = ^DIBTOBMP(hpicture&,1)  // from bmp.dll
      ResHndl&  = LOWORD(hDDB%)     // the bmp
      Palette& = HIWORD(hDDB%)     // the palette
    ENDIF
    ~UnlockResource(hpicture&)
    ~FreeResource(hpicture&)
    PUT 0,0,ResHndl&   //draw it to current DC
    ~^BMPFREE(hDDB%)  // from bmp.dll

Let me add that I highly recommend Sjouke's book, not just because it includes BMP.DLL (which is very useful) but also for the wealth of other information it contains.

James


#: 97199 S12/GFA  (CIS:WINAPC)
    22-Feb-97  05:47:26
Sb: Metafile In Resource
Fm: James V. Schumacher 104166,2104
To: All
Replies:   0

Hi

I about ready to publish my program (thanks in large part to help from Sjouke and a few others in this forum) but I'm still not quite satisfied with some of  the graphics.

On the Macintosh, all my animation graphics are PICT files, which are scaleable draw type formats.  This not only reduces the size of the program considerably, it allows some of my animations to show objects very clearly at various sizes.  Because I've been unable to read/play metafile formated graphics from resources, however, I've been forced to use only bitmaps in my Windows version.  As a result, some of the animations and their backgrounds are no longer very sharp.  If all else fails, I will eliminate the random sizing option in the windows version and store bitmaps as close to the size they will be displayed as possible.   This will have a big impact on the size of my application and take some time.

Therefore, before I make this change, I'm making one last attempt at getting metafile resources to work.   I recall Sjouke thinking that the reason I couldn't get playback  might be because the metafile from which the resource was derived had a header and it needed to be removed.  Since I haven't been able to figure out how, I decided to just try a metafile without the placeable header.   I am positive that the one I am using does not have a header because I am able to play it with the following code

hmf& = GetMetaFile(f$)
MAPMODE MM_ANISOTROPIC
VIEWPORT 0,50,_X,_Y,_X,_Y
~PlayMetaFile(_DC(),hmf&)

After I add it to my .res file and compile it into a DLL, I am using the small program  below to test loading and playing it.

OPENW #1
gAppPath$ = CHR$(_DRIVE) + ":" + DIR$(0) 'path to folder containing application
LTResFilePath$ = gAppPath$ + "\METATEST.DLL" //contains metafile
hAPPInst& = LoadLibrary(LTResFilePath$)
resID$ = "BUG"  //the picture of the bug from one of the examples
KILLEVENT //needed to kill extra paint
DO
  SLEEP
  SWITCH MENU(11) // menu(1)
  CASE WM_PAINT // CASE 21
    hrsc& = FindResource(hAPPInst&,resID$,"METAFILE")
    hmf& = LoadResource(hAPPInst&,hrsc&)
    IF hmf& <> 0
       TEXT 10,200,"allocate hmf& is nonzero"
    ENDIF
    mf% = LockResource(hmf&)
    ~PlayMetaFile(_DC(),hmf&)
  ENDSWITCH
UNTIL MENU(1) = 4
~FreeResource(hmf&)
CLOSEW #1
END

Unfortunately, what I am finding is that although the LoadResource file is outputing a non-zero handle, I am still not getting any metafile played to the screen.   Perhaps when I add the non-placeable header metafile to my Borland Resource Workshop .res file, it doesn't keep that characteristic?  I don't know since it won't let me examine it once it is loaded.  To be honest, I'm not sure I could tell even it it did :).   Anyway, do any of you (Sjouke?) see anything wrong with my test code.  Could you perhaps try this with your resource workshop programs?  If it worked with yours, I would go out an buy it, as well as COREL DRAW, which Sjouke said allows one to save metafiles without the header ... none of the graphics programs I have do this :( .

Thanks,

James


#: 97204 S12/GFA  (CIS:WINAPC)
    23-Feb-97  10:13:17
Sb: #97199-Metafile In Resource
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

After you have obtained a global handle to a memory block using Loadresource, you must call SetMetaFileBits(hGlob) and pass it the obtained handle. The handle to the metafile returned by SetMetafileBits (hmf) is passed to Playmetafile(). hGlob should be deleted using FreeResource and your application should free the hmf handle by calling the DeleteMetaFile function.

This should work.

Greetings, SH


#: 97219 S12/GFA  (CIS:WINAPC)
    25-Feb-97  02:06:08
Sb: Metafile Resource YES!
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036 (X)
Replies:   0

Hi Sjouke,

I tried what you suggest and couldn't get it to work ... BUT, in the process of further fiddling, discovered the real problem.  I needed MAPMODE and VIEWPORT statements!  Now it works!!!  Thanks for making me fiddle with it some more. :)

Here's the final code:

OPENW #1
gAppPath$ = CHR$(_DRIVE) + ":" + DIR$(0) 'path to folder containing application
'load no-header metafile formated picture from resources
LTResFilePath$ = gAppPath$ + "\METATEST.DLL" //contains metafile
hAPPInst& = LoadLibrary(LTResFilePath$)
resID$ = "BUG"  //a noheader metafile from Soujke's book
hrsc& = FindResource(hAPPInst&,resID$,"METAFILE")
hmf& = LoadResource(hAPPInst&,hrsc&)
mf% = LockResource(hmf&) //is this needed?
KILLEVENT //needed to kill extra paint
DO
  SLEEP
  SWITCH MENU(11) // menu(1)
  CASE WM_PAINT // CASE 21
    TEXT 10,10,"metafile visible if no placeable header"
    MAPMODE MM_ANISOTROPIC
    VIEWPORT 0,50,_X,_Y,_X,_Y
    ~PlayMetaFile(_DC(),hmf&)
  ENDSWITCH
UNTIL MENU(1) = 4
~FreeResource(hmf&)
CLOSEW #1
END

It only works with no placeable header metafiles.  Now my question is what is the least expensive method of converting metafiles that have headers to metafiles without headers.  Any shareware packages that will do this.  If not, you mentioned using Corel Draw.  May I ask what version?

James


#: 97300 S12/GFA  (CIS:WINAPC)
    01-Mar-97  21:25:17
Sb: #97293-Application Icon
Fm: GFA Germany 75300,3224
To: James V. Schumacher 104166,2104
Replies:   0

James,

create a RES file containing your icon. Let's assume you call it test.res.
Then edit the ~gfa.lnk file at the point where ~gfa.res is written (change it to test.res). Then everything should work. 

BTW: The icon must be named as "1" within the RES file

Sven, GFA


#: 97327 S12/GFA  (CIS:WINAPC)
    04-Mar-97  00:12:12
Sb: #WritePrivateProfile bug?
Fm: James V. Schumacher 104166,2104
To: ALL
Replies:   1

Hi,

The Windows SDK Reference 2 states the following with regards to the lpszEntry parameter of  the WritePrivateProfileString API: "If the parameter is NULL, the entire section, including all entries within the section, is deleted."

Well, it doesn't do that in the following little program.

OPENW #1
gAppPath$ = CHR$(_DRIVE) + ":" + DIR$(0)
pathOfProfile$ = gAppPath$ + "\test.ini" + CHR$(0)
//create profile if it doesn't already exist
IF EXIST(pathOfProfile$) = FALSE
  OPEN "a",#7,pathOfProfile$
  CLOSE #7
ENDIF
//now open for both reading and writing
OPEN "u",#7,pathOfProfile$
//define constant profile variables
tmpLen = 100
tmp$ = SPACE$(tmpLen)
//now write to profile
sectionName$ = "sectionName&" + CHR$(0)
entryName$ = sectionName$
tmp$ = "test" + CHR$(0)
f! = WritePrivateProfileString(V:sectionName$,V:entryName$,V:tmp$,V:pathOfProfile$)
//now clear profile entry
sectionName$ = "sectionName&" + CHR$(0)
entryName$ = CHR$(0)
tmp$ = CHR$(0)
f! = WritePrivateProfileString(V:sectionName$,V:entryName$,V:tmp$,V:pathOfProfile$)
CLOSE #7
CLOSEW #1

Am I missing something or have I encountered another  Windows bug?

Yours,

James


#: 97329 S12/GFA  (CIS:WINAPC)
    04-Mar-97  01:10:03
Sb: #97327-#WritePrivateProfile bug?
Fm: James V. Schumacher 104166,2104
To: James V. Schumacher 104166,2104
Replies:   1

Hi,

Ignore my question.  Once again I figured it out the answer just after posting!  Turns out that to delete a given section in a private profile  you have to use the following:

f! = WritePrivateProfileString(V:sectionName$,NULL,NULL,V:pathOfProfile$)

I guess that CHR$(0) is not the same as NULL.

James


#: 97335 S12/GFA  (CIS:WINAPC)
    04-Mar-97  10:02:02
Sb: #97329-WritePrivateProfile bug?
Fm: GFA Germany 75300,3224
To: James V. Schumacher 104166,2104
Replies:   0


>>I guess that CHR$(0) is not the same as NULL.<<
Of course it is NOT.
The reserved word NULL means "0", the number zero.
And CHR$(0) is the character with index 0 in the character table.

BTW: Why do you open the INI file with GFA commands? That doesn't make sense.
The API function Write(Private)ProfileString and the appropriate reading functions open, read, and close the INI files themselves. Don't use the GFA commands to avoid a file sharing conflict (only within a network possible, on a single PC there's no problem).

Sven, GFA


#: 97376 S12/GFA  (CIS:WINAPC)
    06-Mar-97  17:32:03
Sb: #97365-WritePrivateProfile bug?
Fm: GFA Germany 75300,3224
To: James V. Schumacher 104166,2104 (X)
Replies:   0

James,

"What was confusing in this case is having insert a number NULL in a parameter location that otherwise calls for a string. "
If a string parameter is expected (for DLL calls, that include API calls, of course), GFA-BASIC automatically adds a CHR$(0) to $-Vars and then calls the function with the string's handle, i.e. there will ALWAYS be numbers passed as parameters (handles are numeric, of course), and if you have to pass a NULL string in conjunction with API calls, the SDK help always means NULL, i.e. "0".

Sven, GFA


#: 97410 S12/GFA  (CIS:WINAPC)
    09-Mar-97  09:30:00
Sb: #97328-#32k clipboard
Fm: John Findlay 100130,1771
To: PETER WHALEN 100416,3156 (X)
Replies:   1

Peter, I don't know if you received any code. Try the listing below.

John

w& = _X, h& = _Y

OPENW #1,0,0,w& / 6 * 3,h& / 4 * 3,~15

OPEN "i",#1,"e:\basic\windows.h"        // 162K file
hmem& = GlobalAlloc(GHND,LOF(#1) + 1)   // Plus one byte so as NULL terminated
adr% = GlobalLock(hmem&)                // Lock and get address
'
@LoadHuge(adr%, LOF(#1))                // Load the file into memory
adr% = @CopyClip(hmem&)
CLOSE #1
~GlobalDiscard(hmem&)
PRINT "Press Mouse"
REPEAT
UNTIL MOUSEK
CLOSEW #1
EDIT
PROCEDURE LoadHuge(pointer%,len%)
  LOCAL count%=0, maxlen%, offset%=LOCARD(pointer%)

  '=================================================
  ' This routine is needed to load something
  ' into a memory block of more than 64K.
  ' It will work for files of less than 64K as well.
  '=================================================
  maxlen% = IMIN(32768 - offset%,len%)
  WHILE count% < len%
    BGET #1,_Huge(pointer%,count%),maxlen%
    count% += maxlen%
    maxlen% = IMIN(32768,len% - count%)
  WEND
RETURN
FUNCTION CopyClip(mem&)
  ~GlobalUnlock(mem&)                   // Unlock memory first
  IF OpenClipboard(WIN(1))
    ~EmptyClipboard()
    ~SetClipboardData(CF_TEXT,mem&)
    ~CloseClipboard()
  ELSE
    ~ALERT(1,"Could not copy to ClipBoard",1,"Ok")
  ENDIF
  RETURN GlobalLock(mem&)               // Lock memory and return address
ENDFUNC


#: 97411 S12/GFA  (CIS:WINAPC)
    09-Mar-97  11:24:08
Sb: #97398-DLG OPEN
Fm: Sjouke Hamstra 100741,1036
To: Jeffrey Heywood 106161,1624
Replies:   0

Hi Jeffrey,

Sorry, I  left you puzzled. I quickly knocked up a small program that 'll do just what you want. (I uploaded it as well).

//   SELDIR.GFW - Directory Dialog box //   (C) 1997 Sjouke Hamstra, Software Design Engineer, GFA Intermediary //   e-mail: 100741.1036@compuserve.com

//   You have a royalty-free right to use, modify, reproduce and //   distribute this sample file, provided that you don't delete //   the copyright message when distributing this file.

DEFWRD "a-z" IF @SelDir(path$)
  ~MessageBox(0,"You selected the
directory:"+CHR$(13,13)+path$+CHR$(13,13)+"(c) 1997 Sjouke Hamstra, GFA Intermediary","DlgDir",MB_OK | MB_ICONEXCLAMATION) ENDIF END

DEFFN DlgMess(Wnr,Id,NotMess) = (_Mess=WM_COMMAND && _hWnd = DLG(Wnr) && _wParam = Id && HIWORD(_lParam) = NotMess)

FUNCTION  SelDir(VAR path$)
  LOCAL CurPath$, FileName$, Finished = 0
  LOCAL p$=STRING$(256,0)

  CurPath$ = CHR$(_DRIVE) + ":" + DIR$(0)
  IF RIGHT$(CurPath$) != "\" THEN CurPath$ = CurPath$ + "\"

  DLG 3D ON
  DLG BASE BOLD

  DIALOG #0,(SYSMETRIC(SM_CXSCREEN)-270)/2,(SYSMETRIC(SM_CYSCREEN)-
250)/2,270,250,"Dirselect box",$40,-11,"MS Sans Serif"
    CONTROL "Ok",1,"button",$10010001,170,20,85,25
    CONTROL "Cancel",2,"button",$10010000,170,50,85,25
    CONTROL "Directory:",103,"static",$1000000b,30,10,80,20
    CONTROL "Path$",104,"static",$10000000,30,30,120,20
    CONTROL "Text",105,"listbox",$10a10043,30,60,120,110
    CONTROL "",106,"combobox",$10243,30,190,120,95
    CONTROL "About",107,"button",$10010000,170,90,85,25
  ENDDIALOG
  SHOWDIALOG #0

  ~DlgDirList(DLG(0),path$,105,104,$8010)               // fill list box with
directories
  ~DlgDirListComboBox(DLG(0),path$,106,104,$4000)       // fill combo box
with drives
  SENDMESSAGE DLGITEM(0,106),CB_SETCURSEL,_DRIVE - 65,0 // select current
drive

  DO
    GETEVENT
    IF @DlgMess(0,105, LBN_DBLCLK)              // directory list box
selection
      ~DlgDirSelect(_hWnd,V:p$,105)             // get selected directory
      ~DlgDirList(_hWnd,V:p$,105,104,$8010)     // fill list box with
directories

    ELSE IF @DlgMess(0,106, CBN_SELCHANGE)      // drive combo box selection
      ~DlgDirSelectComboBox(_hWnd,V:p$,106)     // chdrive and get new path
      ~DlgDirList(_hWnd,V:p$,105,104,$8010)     // fill list box with
directories

    ELSE IF @DlgMess(0,IDOK, BN_CLICKED)        // OK button
      path$ = CHR$(_DRIVE) + ":" + DIR$(0)
      Finished = IDOK

    ELSE IF @DlgMess(0,IDCANCEL, BN_CLICKED)    // Cancel button
      path$ = "", Finished = IDCANCEL

    ELSE IF @DlgMess(0,107, BN_CLICKED)         // About button
      ~MessageBox(0,"(C) Sjouke Hamstra 1997, GFA Intermediary","SELDIR -
Directory Dialog box",MB_OK | MB_ICONEXCLAMATION)

    ENDIF

  UNTIL MENU(1) = 4 || (Finished)
  CLOSEDIALOG #0
  DLG 3D OFF

  CHDRIVE CurPath$                      // reset old drive
  CHDIR MID$(CurPath$,3)                // reset old directory

  RETURN (Finished = IDOK)

ENDFUNC


#: 97452 S12/GFA  (CIS:WINAPC)
    12-Mar-97  12:38:10
Sb: Printer problem
Fm: Bob Springett 100772,452
To: All
Replies:   0

This following:-piece of code sets up lines and columns and prints via a Panasonic KX-P4401 laser type printer.
Could anyone explain to me why the first loop starts the printer in action in about 4 seconds ( printing 22 horizontal lines) but the second ( poresently 'Remmed' out) takes over 2 minutes before it  starts to respond ( printing 8 vertical lines). I've tried LINE ,PLOT, ~LineTo with slightly modified loops but the vertical lines are always that much slower.
Regards 
Bob
PS I think perhaps the driver which is the driver I think supplied with my recently installed
W95 may be the problem.
OPENW #1
p& = PrinterDC()
IF p&
  SETDC p&
  FONT FAMILY 0,QUALITY 0
  FONT "roman",HEIGHT 40,WIDTH 0,WEIGHT FW_BOLD
  FONT ORIENTATION 0,ESCAPEMENT 0,ITALIC 0,UNDERLINE 0
  FONT STRIKEOUT 0,CHARSET OEM_CHARSET TO fnt&
  SETFONT fnt&
  ~Escape(p&,STARTDOC,4,"TEST",0)
  y& = 550
  FOR count1& = 1 TO 22
    DRAW 200,y& TO 2230,y&  ' Horizontal line drawer  1st loop
    ADD y&,100
  NEXT count1&
  ' x& = 200
  ' FOR count2& = 1 TO 8
  ' DRAW x&,550 TO x&,2650 'Vertical line drawer  2nd loop
  ' ADD x&,290
  'NEXT count2&
  ~Escape(p&,NEWFRAME,0,0,0)
  ~Escape(p&,ENDDOC,0,0 ,0)
ENDIF
FREEDC (p&)
CLOSEW #1


#: 97483 S12/GFA  (CIS:WINAPC)
    14-Mar-97  09:51:16
Sb: #97476-Switching to Internet
Fm: Sjouke Hamstra 100741,1036
To: Dominic Powlesland 100417,1770
Replies:   0

Hi Dominic,

 >> As long as we dont use the valuable libraary functions that helps people
like  me to see how things should be done I would be all for a move to the NET  anything that will give GFA a more comprehensive coverage has to be good like  meany others in this forum I use it as the langauge of choice,however I am  woried that ifit does not get more exposure it might go away. A nightmare <<

We don't have give up the library. There is a very good Internet ftp site which provides many examples and GFA demo's. It has an incoming directory as well, where you can put new uploads.

ftp://ftp.startrek.in-trier.de/

However, GFA makes it easy for you to reach this site by going to their homepage at:

http://ourworld.compuserve.com/homepages/gfasoft

Other interesting GFA info can be found at:

http://www.dortmund.netsurf.de/~erenner

Greetings, SH


#: 97478 S12/GFA  (CIS:WINAPC)
    14-Mar-97  04:42:12
Sb: #Windows Logo Key
Fm: James V. Schumacher 104166,2104
To: All
Replies:   1

More on my Windows Logo Key Problem:

My program has a callback declared as follows:

CB -1,0 TO -1,onEventdoUserEvent

Within that callback I placed the following code:

  SELECT WIN()
    '
  CASE g_drillWind&
    //added to prevent any key but spacebar and escape key from affecting drills
      IF wparam& = VK_ESCAPE OR wparam& = VK_SPACE
      'ok let it pass
    ELSE
      BEEP
      RETVAL 0 'prevent keystroke from reaching windows procedure
    ENDIF

   etc...

This code causes a beep when any key other than the escape or space is pressed. It beeps when the Windows Logo Key is pressed.  Now my understanding is that by sending a RETVAL 0 back, the message is supposed to be deleted.  Is that correct?  Then why does the taskbar still popup?  I also wrote a tiny program to print out the _wparam codes.  The code for the Windows Logo key is 91 and it seems to be printed to the window before the taskbar pops up.  Does anyone have an idea what is going on and how to circumvent the taskbar being activated by this key? 

James


#: 97484 S12/GFA  (CIS:WINAPC)
    14-Mar-97  09:51:17
Sb: #97478-Windows Logo Key
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

The MSDN solves your problem:

"To disable task switching, the program must prevent the user from accessing the Task List and from using mouse or keystroke combinations to switch to other applications. NOSWITCH takes the following four steps to disable task switching:
 1.	Subclasses the desktop window to prevent the Task List from being
displayed when the user double-clicks the desktop window.
 2.	Traps three wParam values (SC_NEXTWINDOW, SC_PREVWINDOW, and
SC_TASKLIST) for the WM_SYSCOMMAND message to prevent the user from using key combinations to switch to another task. If the application is run as a maximized window, this step is adequate to prevent switching tasks. However, the application must prevent the window from being restored or minimized, so this method has limitations.
 3.	Enumerates all top-level windows and disables the windows that do not
belong to the application to prevent other applications from activating themselves.
 4.	Disables menu items associated with switching tasks whenever it
receives a WM_INITMENUPOPUP message for the System menu.

Before exiting the application, NOSWITCH reverses the effects of these actions. NOSWITCH is included in the Microsoft Knowledge Base Software/Data Library. On the Microsoft Developer Network CD, search for the numbers prefixed with "S" and "Q" in the Keywords section below for more information on this sample application."

I'll mail you the source code (C).

Greetings, SH


#: 97507 S12/GFA  (CIS:WINAPC)
    15-Mar-97  12:02:06
Sb: #97488-#Book
Fm: Sjouke Hamstra 100741,1036
To: Dale Bryant 73134,1500 (X)
Replies:   1

Hi Dale,

 >> After reading your book I may end up knowing more about GFA  than I
wanted  to. <G>  Seriously, you have explained many things that I have wanted to  know. <<

That's why I wrote it in the first place. I have wondered how people could use GFABasic without reading my book first ;-).

>> I sure hope you follow with a sequel.  I would love to see more on the API as called from GFA.  A concise explanation of creating dynamic link    <<

There will be no sequel, that is, I'm developing for my new book on GFAWIN95, and this book will bring you a lot of new stuff that covers both Windows 3.1 and Win32. In this I hope to create an Appendix or help file covering all(!) API calls. I'm currently thinking on how to to this in an original and short form. However, if GFA is going to put the API calls in there help files I will drop the idea.

Although there will be no follow up on my book, I might surprise you with something new I'm currrently working on. However this project is so complicated and huge for one person I might eventually drop it. (Curious? Ok, I'm working on a Visual GFABasic Builder)

Greetings, SH


#: 97523 S12/GFA  (CIS:WINAPC)
    17-Mar-97  09:02:21
Sb: #97512-Comp./Interpr. problem
Fm: Sjouke Hamstra 100741,1036
To: Ingmar Brunken 100573,3013
Replies:   0

Hi Ingmar,

I do remember having problems using EXEC and WinExec, and I switched to ShellExecute(). Try it.

Haven't seen your comment yet on switching to Internet.

Greetings, SH


#: 97524 S12/GFA  (CIS:WINAPC)
    17-Mar-97  10:23:00
Sb: #97512-Comp./Interpr. problem
Fm: GFA Germany 75300,3224
To: Ingmar Brunken 100573,3013
Replies:   0

Ingmar,

WinExec returns an error code, and not a window handle!
If you want to have Notepad on top (or wait with program execution until Notepad ends)
you must call WinExec, then look for Notepad in the task queue (FindWindow) and get the
handle this way. If you want to wait for Notepad to end, you must wait for the handle retrieved via
FindWindow to be destroyed. (requires a message loop only looking for changes of Notepad's
window handle, best done in callback).

Greetings

Sven, GFA Software


#: 97532 S12/GFA  (CIS:WINAPC)
    18-Mar-97  01:32:06
Sb: Windows Logo Key
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036 (X)
Replies:   0

Hi Sjouke,

I've been experimenting with the NOSWITCH.EXE program you sent me.  While it does prevent one from opening up the task bar with the mouse, the task bar still appears when the Windows Logo Key is pressed!  The open folder and running application items on the task bar don't do anything when clicked (they appear to be disabled), but the items which appear when the START item on the task bar is clicked still function normally.   In other words, I can still open other folders and run any other application even when the NOSWITCH.EXE window is tellling me that the task switch is disabled.    I need something that is going to totally prevent the task bar, including the START item, from appearing at all when the Windows Logo Key is pressed.   Any other ideas?  

James


#: 97622 S12/GFA  (CIS:WINAPC)
    22-Mar-97  06:04:05
Sb: #97562-Windows Logo Key
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036
Replies:   0

>>  Try to display the keyboard messages and look for the Windows Logo Key and trap it. <<

Hi Sjouke,

Well, I gave it my best shot but as far as I can tell, trapping the Windows Logo Key and Alt-Tab and Ctrl-Esc key sequences by subclassing the entire window and returning a RETVAL 0 when they are encountered doesn't work.   Below is the code I tried (maybe you can see what's wrong ... if there is anything wrong).   I also tried trapping the messages suggested in the NOSWITCH example.  Again, no effect.

_CB (1) = doKeyTrap(WWWL)
g_drillWind& = 1
OPENW #g_drillWind&
'subclass it to doKeyTrap to filter out certain keystrokes
gDrillWindSubClass = SetWindowLong(WIN(g_drillWind&),GWL_WNDPROC,_CB(1))
DO
  PEEKEVENT
UNTIL MENU(1) = 4
'remove drill window subclassing
~SetWindowLong(WIN(g_drillWind&),GWL_WNDPROC,gDrillWindSubClass)
CLOSEW #1
'
PROCEDURE doKeyTrap(hwnd&,msg&,wparam&,lparam%)
  PRINT "code";_wParam
  SELECT msg& //branch based on message number
  CASE WM_CHAR //keyboard character entered
    IF WIN() = g_drillWind&
      '//prevents any key but spacebar and escape key from affecting drills
      IF wparam& = VK_ESCAPE OR wparam& = VK_SPACE
        'ok let it pass
        RETVAL CallWindowProc(gDrillWindSubClass,hwnd&,msg&,wparam&,lparam%) //pass character on untouched
      ELSE
        'prevent keystroke from reaching windows procedure
        'BEEP
        RETVAL 0
      ENDIF
    ELSE
      RETVAL CallWindowProc(gDrillWindSubClass,hwnd&,msg&,wparam&,lparam%) //pass character on untouched
    ENDIF
  CASE WM_SYSCOMMAND
    //doesn't beep when windows logo key, alt-tab or ctrl-esc pressed
    IF wparam& = SC_NEXTWINDOW OR wparam& = SC_PREVWINDOW OR wparam& = SC_TASKLIST
    '  RETVAL 0
      BEEP
    ENDIF
      'ELSE
    RETVAL CallWindowProc(gDrillWindSubClass,hwnd&,msg&,wparam&,lparam%) //pass character on untouched
  CASE WM_SYSKEYDOWN,WM_SYSKEYUP,WM_SYSCHAR
    // seems to detect alt key or key following alt but doesn't stop alt-tab
    IF WIN() = g_drillWind&
      ' BEEP
      RETVAL 0
    ELSE
      RETVAL CallWindowProc(gDrillWindSubClass,hwnd&,msg&,wparam&,lparam%) //pass character on untouched
    ENDIF
  CASE WM_KEYDOWN
    //prevents any key but spacebar and escape key from affecting drills
    //detects windows logo key press but doesn't stop it.
    //detects ctrl key but doesn't stop ctrl-esc
    IF WIN() = g_drillWind&
      IF wparam& = VK_ESCAPE OR wparam& = VK_SPACE   //ensures inputs are numbers
        'ok let it pass
        RETVAL CallWindowProc(gDrillWindSubClass,hwnd&,msg&,wparam&,lparam%) //pass character on untouched
      ELSE
        'prevent keystroke from reaching windows procedure
        'BEEP
        RETVAL 0
      ENDIF
    ELSE
      RETVAL CallWindowProc(gDrillWindSubClass,hwnd&,msg&,wparam&,lparam%) //pass character on untouched
    ENDIF
    //doesn't beep
     CASE WM_INITMENUPOPUP
       BEEP
       RETVAL CallWindowProc(gDrillWindSubClass,hwnd&,msg&,wparam&,lparam%) //pass character on untouched
  DEFAULT
    RETVAL CallWindowProc(gDrillWindSubClass,hwnd&,msg&,wparam&,lparam%) //pass character on untouched
  ENDSELECT
RETURN

Now I'm going to try installing a Keyboard Hook Procedure.  Someone on another forum suggested it might work.  I'll let you know what happens.

James


#: 97624 S12/GFA  (CIS:WINAPC)
    22-Mar-97  17:21:04
Sb: Windows Logo Key
Fm: Friedrich Rode 100602,702
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

>>I need something that is going to totally prevent the 
task bar<<

try following:

Systemwide Mouse and Keyboardinput locked (Taskswitching):

// Possibility 1:   
 ~SetSysModalWindow(WIN(1))
---------------------------------------------------------
// Possibility 2:   
OPENW #1
DLL #1,"user"
  DECL BOOL LockInput(w,w,w)
ENDDLL

l! = ^LockInput(0,WIN(1),-1)
DO
  GETEVENT
UNTIL MOUSEK = 2
l! = ^LockInput(0,WIN(1),0)
FREEDLL 1
CLOSEW #1
-------------------------------------
// Possibility 3:  
Mouseinput for Systemtray locked:

OPENW #1
h& = FindWindow("Shell_Traywnd","")
DISABLEW h&
DO
  GETEVENT
UNTIL MOUSEK = 2
ENABLEW h&
CLOSEW #1

I think in this case the start key is only over a hook addressable.

Greetings Friedrich


#: 97629 S12/GFA  (CIS:WINAPC)
    23-Mar-97  11:41:25
Sb: #97622-Windows Logo Key
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

 >> Now I'm going to try installing a Keyboard Hook Procedure.  Someone on
another forum suggested it might work.  I'll let you know what happens.   <<

that's a good idea. You may find these programs useful when developing the hooks:

// KEYCALL - Uses the KEYHOOK.DLL DEFWRD "a-z"

Dll #1,"KEYHOOK.DLL"
  DECL WORD InstallHook(w,w)
ENDDLL

Titlew #1,"KeyHook" OPENW #1,200,200,450,250,~15 ~^InstallHook(WIN(1),1) ON MENU MESSAGE GOSUB HandleMessage DO
  SLEEP
  IF MENU(1) = 1 THEN ~DestroyWindow(DLG(-1,101))
UNTIL MENU(1)=4 exit End

PROCEDURE exit
  ~^InstallHook(WIN(1),0)
  FREEDLL 1
  CLOSEW #1
RETURN

PROCEDURE HandleMessage
  SWITCH MENU(1)
  CASE 1
    If Menu(11) = WM_CHAR Then ? Hex$(_wparam)'
  CASE 21
  ENDSWITCH
RETURN -----------------------------------------------------------

// KEYHOOK.GFW DEFWRD "a-z" $LIBRARY KEYHOOK

PROCEDURE LIBMAIN(hInst,DSeg,HpSz,lpCmd%)
  InitHook()
  RETVAL 1
RETURN

PROCEDURE WEP(SysExit)
  ~^UnHookWindowsHookEx(hhook%)
RETURN

PROCEDURE InitHook()
  DLL #1,"USER"
    DECL DWORD SetWindowsHookEx(w,l,w,w)
    DECL BOOL  UnHookWindowsHookEx(l)
    DECL DWORD CallNextHookEx(l,w,w,l)
  ENDDLL
RETURN

PROCEDURE InstallHook(Hwnd,Flag)
  $EXPORT INSTALLHOOK
  IF (Flag)
    _CB (10)=HookProc(wwl)
    hWndMain = Hwnd
    hTask = GetCurrentTask()
    hhook% = ^SetWindowsHookEx(WH_KEYBOARD,_cb(10),_instance,NULL)
  ELSE
    ~^UnHookWindowsHookEx(hhook%)
  ENDIF
  RETVAL 1
RETURN

PROCEDURE HookProc(nCode,wParam,lParam%)
  If nCode = HC_ACTION && nCode >= 0  && wParam = VK_ESCAPE
    Beep
    Retval 1
  Else
    RETVAL ^CallNextHookEx(hhook%,nCode,wParam,lParam%)
  EndIf
RETURN

Greetings, SH


#: 97662 S12/GFA  (CIS:WINAPC)
    25-Mar-97  09:12:02
Sb: #97578-Right Justified Menus 
Fm: Sjouke Hamstra 100741,1036
To: Dominic Powlesland 100417,1770 (X)
Replies:   0

Hi Dominic,

I was reading some stuff on new Windows 95 window styles and ran into the following:

+	WS_EX_RIGHT   Gives a window generic right-aligned properties. This depends on the window class. +	WS_EX_RIGHTSCROLLBAR   Places a vertical scroll bar (if present) to the right of the client area. This is the default. +	WS_EX_RTLREADING   Displays the window text using right-to-left reading order properties.

You set them using:

  ~SetWindowLong(Win(1),GWL_EXSTYLE,WS_EX_RTLREADING%)

This works only on Windows 95 systems!

Greetings, SH


#: 97700 S12/GFA  (CIS:WINAPC)
    28-Mar-97  09:10:17
Sb: Windows Logo Key
Fm: James V. Schumacher 104166,2104
To: All
Replies:   0

Hi Fredrich and Sjouke,

Thank you both for your suggestions so far in dealing with my taskbar problem. 
I haven't succeeded in getting the hook approach to work yet but I am making progress.  The following function (thanks Fredrich), when called with a FALSE parameter, does prevent the task bar from showing when the mouse is moved over it, the CTRL-ESC keys are pressed or the Windows Logo Key is pressed.   

PROCEDURE showTaskBar(cond!)
  hSysTray& = FindWindow("Shell_TrayWnd",NULL)
  IF hSysTray&
    IF cond! = TRUE
      ~ShowWindow(hSysTray&,SW_SHOW)
    ELSE
      ~ShowWindow(hSysTray&,SW_HIDE)
    ENDIF
  ENDIF
RETURN

HOWEVER, there is still a problem.  When the Windows Logo Key is pressed, the popup items that appear when the START item on the taskbar is normally selected with the mouse appear!  Fredrich, is this what you meant by 

>> I think in this case the start key is only over a hook addressable.<<

or is there an easy way to stop this too?

Also, is there a similar way  to defeat the alt-tab taskswitching popup?  The above program does not affect it nor any of the non-hook techniques I've tried.

James


#: 97711 S12/GFA  (CIS:WINAPC)
    29-Mar-97  18:58:08
Sb: Messages
Fm: Bob Springett 100772,452
To: Sjouke Hamstra 100741,1036
Replies:   0

Sjouke,
I sent this request this morning and since it has not appeared on the forum I can only assume it has gone to your private number, for which I do apologise.
I am using a DO LOOP in which I am interrogating keyboard calls with an IF menu(11)=WM_KEYDOWN followed by a|=LOBYTE(HIWORD(Menu(13))). It works perfectly on the function keys and the END key but when I try to use the enter key (scancode 28),nothing). I am using this outside of but interrogating what is going on inside a DIALOG box. I have tried the help file under HIBYTE and ENTER is trapped O.K.
Is there something I am missing here.
Incidentally I bought your book and since this morning have tried the program on page 78 which works O.K. outside the application but when I use the same principles inside
everything else seems to work O.K. but the ENTER key. I am using nothing inside the application which does anything with the ENTER key, to my knowledge.
Kindest regards
Bob


#: 97716 S12/GFA  (CIS:WINAPC)
    30-Mar-97  09:54:25
Sb: Enter in Edit control
Fm: Sjouke Hamstra 100741,1036
To: Bob Springett 100772,452 (X)
Replies:   0

Hi Bob,

>>I need to work with edit controls in a dialog box and I need the ENTER key to drive the Focus to the next  edit control and to do other things. There are 180 edit controls <<

That's quite something different, use the following code as a start.

/* The edit control has the ES_MULTILINE style without /* the ES_AUTOVSCROLL style. When the edit control has the input focus /* we can respond to a Enter press by the WM_KEYDOWN message.

DIALOG #0,70,5,300,200,"GFA Basic",$10000000//************** 2
  CONTROL "text",100,"edit",$10810494,10,30,120,20
  CONTROL "text",101,"edit",$10810494,10,60,120,20
  'CONTROL "Text",100,"edit",$50800000,40,30,164,24// *********3
  'CONTROL "Text",101,"edit",$50800000,40,60,164,24// *********3
ENDDIALOG // *****************************************************4 SHOWDIALOG #0// ************************************************5

~SetFocus(DLG(0,100)) DO
  GETEVENT
  /*
  /* check Enter press in Edit control ...
  /*
  IF _Mess = WM_KEYDOWN && _wParam = 13 && GetFocus() = DLG(0,100)
    ~SetFocus(DLG(0,101))
  ENDIF
LOOP

Greetings, SH


#: 97752 S12/GFA  (CIS:WINAPC)
    01-Apr-97  14:31:00
Sb: #97743-Right Justified Menus 
Fm: Sjouke Hamstra 100741,1036
To: Dominic Powlesland 100417,1770
Replies:   0

Hi Dominic,

From WINUSER.H Win32 SDK:

/*
 * Extended Window Styles
 */
#define WS_EX_DLGMODALFRAME  0x00000001L #define WS_EX_NOPARENTNOTIFY 0x00000004L #define WS_EX_TOPMOST        0x00000008L #define WS_EX_ACCEPTFILES    0x00000010L #define WS_EX_TRANSPARENT    0x00000020L #if(WINVER >= 0x0400) #define WS_EX_MDICHILD          0x00000040L #define WS_EX_TOOLWINDOW        0x00000080L #define WS_EX_WINDOWEDGE        0x00000100L #define WS_EX_CLIENTEDGE        0x00000200L #define WS_EX_CONTEXTHELP       0x00000400L

#define WS_EX_RIGHT             0x00001000L #define WS_EX_LEFT              0x00000000L #define WS_EX_RTLREADING        0x00002000L #define WS_EX_LTRREADING        0x00000000L #define WS_EX_LEFTSCROLLBAR     0x00004000L #define WS_EX_RIGHTSCROLLBAR    0x00000000L

#define WS_EX_CONTROLPARENT     0x00010000L #define WS_EX_STATICEDGE        0x00020000L #define WS_EX_APPWINDOW         0x00040000L

#define WS_EX_OVERLAPPEDWINDOW  (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE) #define WS_EX_PALETTEWINDOW     (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST)

Greetings, SH


#: 97748 S12/GFA  (CIS:WINAPC)
    01-Apr-97  07:58:05
Sb: #Disabling Alt-Tab Switch
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036 (X)
Replies:   1

Hi Sjouke,

I looked over the noSwitch.exe example you sent and, according to it, to disable Alt-Tab switching when the application window is maximized (which mine is),  I need to trap the SC_NEXTWINDOW, SC_PREVWINDOW and SC_TASKLIST wparam values for the WM_SYSCOMMAND message.  I haven't even been able to even detect the WM_SYSCOMMAND message!  I tried the following:

_CB (1) = doKeyTrap(WWWL)
OPENW #1, 0,0,_X,_Y,-1
gWindSubClass% = SetWindowLong(WIN(1),GWL_WNDPROC,_CB(1))
DO
  PEEKEVENT
UNTIL MENU(1) = 4
~SetWindowLong(WIN(1),GWL_WNDPROC,gWindSubClass%)
CLOSEW #1
PROCEDURE doKeyTrap(hwnd&,msg&,wparam&,lparam%)
  SELECT msg&
  CASE WM_SYSCOMMAND
    BEEP    //doesn't beep when alt-tab pressed
    RETVAL CallWindowProc(gWindSubClass%,hwnd&,msg&,wparam&,lparam%)
  DEFAULT
    RETVAL CallWindowProc(gWindSubClass%,hwnd&,msg&,wparam&,lparam%)
  ENDSELECT
RETURN

Any idea what I'm doing wrong?

James


#: 97753 S12/GFA  (CIS:WINAPC)
    01-Apr-97  14:31:01
Sb: #97748-Disabling Alt-Tab Switch
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

 >> I looked over the noSwitch.exe example you sent and, according to it, to
disable Alt-Tab switching when the application window is maximized (which mine is),  I need to trap the SC_NEXTWINDOW, SC_PREVWINDOW and SC_TASKLIST wparam values for the WM_SYSCOMMAND message.  I haven't even been able to even detect the WM_SYSCOMMAND message!  I tried the following:   <<

A few notes:

1. NOSWITCH is intended for Windows 3.1 2. The Start button cannot be trapped using NOSWITCH (I checked, i.e there seems to be no WM_KEYDOWN message) 3. You should try HOOKKEY.DLL 4. According Win32 SDk the Task bar should not be trapped ( I don't know why and I also don't know how to trap it anyway, at least yet!)

It seems you're getting yourself in trouble... If you're interested I converted NOSWITCh to GFA (half an hour work) and it works just like the C code. However it seems of no use for you. Keep me posted!

Greetings, SH


#: 97749 S12/GFA  (CIS:WINAPC)
    01-Apr-97  08:31:11
Sb: #Hook DLL 
Fm: James V. Schumacher 104166,2104
To: James V. Schumacher 104166,2104
Replies:   1

Sjouke and Fredrich,

I noticed a discrepancy in the parameter declarations of the two hookproc example programs that you provided.   Here are the two declarations.

   DLL #11,"user"
    DECL WORD SetWindowsHookEx(W,L,W,W)
    DECL LONG CallNextHookEx(W,W,W,L)
    DECL BYTE UnhookWindowsHookEx(W)
  ENDDLL

  DLL #1,"USER"
    DECL DWORD SetWindowsHookEx(w,l,w,w)
    DECL BOOL  UnHookWindowsHookEx(l)
    DECL DWORD CallNextHookEx(l,w,w,l)
  ENDDLL

I think the former is correct.  True?

James


#: 97751 S12/GFA  (CIS:WINAPC)
    01-Apr-97  14:31:31
Sb: #97749-Hook DLL 
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

 >> I noticed a discrepancy in the parameter declarations of the two hookproc
example programs that you provided.   Here are the two declarations.

   DLL #11,"user"
     DECL WORD SetWindowsHookEx(W,L,W,W)
     DECL LONG CallNextHookEx(W,W,W,L)
     DECL BYTE UnhookWindowsHookEx(W)
   ENDDLL

  DLL #1,"USER"
     DECL DWORD SetWindowsHookEx(w,l,w,w)
     DECL BOOL  UnHookWindowsHookEx(l)
     DECL DWORD CallNextHookEx(l,w,w,l)
   ENDDLL

I think the former is correct.  True?  <<

Certainly not! These hook functions use long pointers!!! (mine are correct ;- ) )

Greetings, SH


#: 97755 S12/GFA  (CIS:WINAPC)
    01-Apr-97  15:20:19
Sb: Disable taskbar
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

Well, I've been walking my dog and gave your problem a thought. I've came up with a simple solution, why not disable the taskbar? The following code seems to work:

DEFWRD "a-z" OPENW #1,200,200,350,350,~15 hShellTray = FindWindow("Shell_TrayWnd",NULL) DISABLEW hShellTray DO
  SLEEP
UNTIL MENU(1)=4 ENABLEW hShellTray CLOSEW #1 END

And now for the entire NOSWITCH code:

// NOSWITCH - Disable task switching // 1-04-1997 Sjouke Hamstra // Derived from NOSWITCH.C

DEFWRD "a-z" hDeskTop = GetDesktopWindow() EnabledTaskSwitch! = TRUE

_CB (0)=DeskTopWndProc(wwwl) _CB (1)=EnumWndProc(wl)

'OPENW #1,200,200,350,350,~15 FULLW #1 CB WIN(1),0 TO -1, WndProc() hSysmenu = GetSystemMenu(WIN(1),0)

MenuCreate()

ON MENU MESSAGE GOSUB HandleMessage DO
  SLEEP
UNTIL finished! CLOSEW #1 END

PROCEDURE WndProc(hWnd,Mess,wParam,lParam%)

  SWITCH Mess
  CASE WM_SYSCOMMAND
    SWITCH (wParam)
    CASE SC_NEXTWINDOW, SC_PREVWINDOW, SC_TASKLIST
      RETVAL 0
    CASE SC_MINIMIZE            /* we don't want to be minimized at this
point */
      IF (!EnabledTaskSwitch!)  /* if the task switch is disabled, then we
return */
        RETVAL 0
      ENDIF
    ENDSWITCH

  CASE WM_INITMENUPOPUP         /* if the task switch is disabled,
    IF (hSysmenu = wParam)      /* then we gray these sysmenu items
      IF (EnabledTaskSwitch!)
        ~EnableMenuItem(hSysmenu, SC_TASKLIST, MF_ENABLED)
        ~EnableMenuItem(hSysmenu, SC_MINIMIZE, MF_ENABLED)
      ELSE
        ~EnableMenuItem(hSysmenu, SC_TASKLIST, MF_GRAYED)
        ~EnableMenuItem(hSysmenu, SC_MINIMIZE, MF_GRAYED)
      ENDIF
    ENDIF
    RETVAL 0

  ENDSWITCH

RETURN

PROCEDURE DeskTopWndProc(hWnd,Mess,wParam,lParam%)

  SWITCH Mess

  CASE WM_SYSCOMMAND
    BEEP

  CASE WM_LBUTTONDBLCLK
    RETVAL 0  //trap the WM_LBUTTONDBCLK message so Task list won't come up
    EXPROC
  ENDSWITCH

  RETVAL CallWindowProc(lpoldDeskTopWndProc%, hWnd, Mess,wParam,lParam%)

RETURN

PROCEDURE EnumWndProc(hWnd,lParam%)
  IF _INSTANCE != GetWindowWord(hWnd, GWW_HINSTANCE)
    IF (lParam%)
      ENABLEW hWnd
    ELSE
      DISABLEW hWnd
    ENDIF
  ENDIF
  RETVAL TRUE
RETURN

PROCEDURE HandleMessage
  SWITCH MENU(1)
  CASE 4
    IF !EnabledTaskSwitch!
      ~SetWindowLong(hDeskTop,GWL_WNDPROC,lpoldDeskTopWndProc%)
      ~EnumWindows(_CB(1),TRUE)
      ENABLEW hShellTray
    ENDIF
    finished! = TRUE
  CASE 21
  ENDSWITCH
RETURN

PROCEDURE MenuHandle
  SWITCH MENU(0)
  CASE 1
    IF EnabledTaskSwitch!
      lpoldDeskTopWndProc% = SetWindowLong(hDeskTop,GWL_WNDPROC,_CB(0))
      ~EnumWindows(_CB(1),0)
      hShellTray = FindWindow("Shell_TrayWnd",NULL)
      DISABLEW hShellTray
      MENU 1,MF_STRING,"Enable Task Switch"
    ELSE
      ~SetWindowLong(hDeskTop,GWL_WNDPROC,lpoldDeskTopWndProc%)
      ~EnumWindows(_CB(1),TRUE)
      ENABLEW hShellTray
      MENU 1,MF_STRING,m$(1)
    ENDIF
    EnabledTaskSwitch! = NOT EnabledTaskSwitch!

  CASE 3
    POSTMESSAGE _hWnd,WM_CLOSE,0,0
  ENDSWITCH

RETURN

PROCEDURE MenuCreate()
  LOCAL i
  DIM m$(20)
  FOR i = 0 TO 20
    READ m$(i)
    EXIT IF m$(i) = "**"
  NEXT i
  MENU m$()
  ON MENU GOSUB MenuHandle
  DATA File,Disable Task Switch,-,Exit,,,**
RETURN

Hope this will do the trick...

Greetings, SH


#: 97762 S12/GFA  (CIS:WINAPC)
    01-Apr-97  21:05:13
Sb: #97753-Disabling Alt-Tab Switch
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036
Replies:   0

Sjouke,

>> 1. NOSWITCH is intended for Windows 3.1 <<

It seems to work fine on my Windows 95 system.

At this point, all I want from NOSWITCH is to learn how to stop the alt-tab key sequence from opening up the task switcher (as opposed to the task bar).  My short test program, which I thought was doing what MainWndProc does in the NOSWITCH example, doesn't even detect the WM_SYSCOMMAND and wparam SC_TASKLIST, etc. messages ... so I'm missing something really important here.

>> 3. You should try HOOKKEY.DLL 

I downloaded it over the weekend.    The problem with using a HOOK to do what NOSWITCH does is that I see no way to intercept a WM_SYSCOMMAND message (because no msg& parameter is passed to the hook ... just wparam and lparam).  The KEYBOARD hook doesn't seem to intercept that message.  Does a CBT hook?   I just downloaded Kyle Marsh's Win32 Hooks document.  Maybe it will provide a clue.

>> 4. According Win32 SDk the Task bar should not be trapped <<

Doesn't Microsoft understand that there are users who shouldn't (in fact, mustn't) have access to the task bar.  Apple does.  I think it was plain stupid to build a feature like this into the operating system without a way of turning it off.  Thanks to Fredrich, I now have the SPY example that hides the start menu popup immediately after it appears.  This isn't ideal.  There is a noticeable blip on the screen as the popup is briefly visible (which is a problem given that my users are autistic) and it messes up my color palettes because the popup contains non-Window colors (which you know that is something I just love to see happen).  It would be much better if I could just cause the popup not to open in the first place.  Microsoft really blew it.

>> If you're interested I converted NOSWITCh to GFA (half an hour work) and it works just like the C code. However it seems of no use for you.  <<

Ohhh, but I AM very interested in seeing that code!!!  It would answer my question about how to prevent the alt-tab key from opening up the task switcher.  Please ... I beg you, send it to me right away!!!

>> Keep me posted! <<

Will do!

Gratefully,

James


#: 97766 S12/GFA  (CIS:WINAPC)
    02-Apr-97  03:42:31
Sb: #97753-Disabling Alt-Tab Switch
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036
Replies:   0

Sjouke,

I have to admit that the keyboard hook code seems to run better when I declare hhook as a long pointer!!  Unfortunately, a dll keyboard hook does not seem to stop the action of ctrl-esc or the windows logo key.  It will detect them but no matter what the retval (0 or 1), the task bar and start menu popup appear.  Curses Microsoft!!!!

Here is the code I put in the hook example you sent me:

PROCEDURE HookProc(nCode,wParam,lParam%)
   IF nCode >= 0
    IF GetKeyState(VK_CONTROL) < 0 //comment out for logo key
      IF wParam =  VK_ESCAPE  //or 91 to detect the logo key
        BEEP //it beeps but doesn't stop the ctrl-esc from working
        BEEP
        RETVAL 1 //tried various values here
      ELSE
        RETVAL ^CallNextHookEx(hhook%,nCode,wParam,lParam%)
      ENDIF
    ELSE
      RETVAL ^CallNextHookEx(hhook%,nCode,wParam,lParam%)
    ENDIF
  ELSE
    RETVAL ^CallNextHookEx(hhook%,nCode,wParam,lParam%)
  ENDIF
RETURN

Perhaps it would work if the hook was thread specific?  I think I read somewhere that they are done before system hook procedures so maybe that would stop the message?  I'll try that next.

Then I'm going to try defeating the alt-tab with a CBTHOOK.  The documentation says it will detect a SYSCOMMAND message.  Well see ....

James


#: 97763 S12/GFA  (CIS:WINAPC)
    01-Apr-97  21:16:10
Sb: #97751-Hook DLL 
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036
Replies:   0

>> Certainly not! These hook functions use long pointers!!! (mine are correct ;- ) ) <<

But I found the following in Kyle Marsh's Windows Hook Sample Application:

hhookMsgFilterHook = SetWindowsHookEx(...)
UnhookWindowsHookEx(hhookMsgFilterHook);
return ((int)CallNextHookEx(hhookMsgFilterHook, ...)

The h in front of hhookMsgFilterHook means handle because his long pointer variables all have lp in front of them?  Maybe this is another one of those cases where it doesn't matter what you declare ... it still works ... until you compile! ;)

James


#: 97764 S12/GFA  (CIS:WINAPC)
    01-Apr-97  22:08:15
Sb: Disable taskbar
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036
Replies:   0

>> DEFWRD "a-z" OPENW #1,200,200,350,350,~15 hShellTray = FindWindow("Shell_TrayWnd",NULL) DISABLEW hShellTray DO
  SLEEP
UNTIL MENU(1)=4 ENABLEW hShellTray CLOSEW #1 END <<

Hi Sjouke, 

Unfortunately, this code just disables the task bar as far as the mouse is concerned.  If your application's window has the focus, the Windows Logo Key still makes the taskbar appear and the START popup menu portion of it will still be enabled.

Several routines were missing in your noswitch code post (EnumWndProc(wl), Handlemessage, MenuHandle) so I tried to isolate just the alt-tab disabling portion:

// NOALTTAB - Disable alt-tab task switching // Derived from NOSWITCH.C
DEFWRD "a-z"
EnabledTaskSwitch! = FALSE  //just turn it off
OPENW #1,200,200,350,350,~15
FULLW #1
CB WIN(1),0 TO -1, WndProc()
DO
  SLEEP
UNTIL MENU(1) = 4 //finished!
CLOSEW #1
END
PROCEDURE WndProc(hWnd,Mess,wParam,lParam%)
  SWITCH Mess
  CASE WM_SYSCOMMAND
    SWITCH (wParam)
    CASE SC_NEXTWINDOW, SC_PREVWINDOW, SC_TASKLIST
      BEEP //it never beeps!
      RETVAL 0
    CASE SC_MINIMIZE  /* we don't want to be minimized at this point/*
      IF (!EnabledTaskSwitch!)  /* if the task switch is disabled, then we return /*
        RETVAL 0
      ENDIF
    ENDSWITCH
  ENDSWITCH
RETURN

When run, as in my test code, it doesn't appear to detect the SC_NEXTWINDOW, SC_PREVWINDOW or SC_TASKLIST messages.  The task switcher is still enabled. It would appear that something more is required to detect and stop these three messages.  Perhaps one of the other routines is necessary too?  Do you have a fully working noswitch code example?  

James


#: 97778 S12/GFA  (CIS:WINAPC)
    03-Apr-97  02:16:09
Sb: #97762-Disabling Alt-Tab Switch
Fm: GFA Germany 75300,3224
To: James V. Schumacher 104166,2104
Replies:   0

Dear James,

now it's time to join your discussion, I think. Please find below some source code that I've just written. These are two files, one that must be compiled into a dll and contains the hook function, the other one as loader.
The result is a program that completely disables the start menu (of course, in Windows95 only). Let me know if you have a version ready that disables task list within Windows 3.x as well. Then we should concenate our source codes and distribute it in the library.

Greetings

Sven, GFA

------------------------------------------------------------------------------------------
SAVE AS HOOKGFW.GFW:
------------------------------------------------------------------------------------------
/* How to disable activating of Windows start menu via logo key or Ctrl-Esc
$LIBRARY TRAPHOOK

PROCEDURE LIBMAIN(hInst&,DSeg&,HpSz&,lpCmd%)
  WH_SHELL% = 10 /* WH_SHELL hook
  HSHELL_TASKMAN% = 7 /* Taskman should appear

  _CB (2)=ShellProc(wwl)
  lpShellProc% = 0

  DLL #1,"user" /** declare extended hook functions
    DECL LONG SetWindowsHookEx(w,l,w,w)
    DECL LONG CallNextHookEx(l,w,w,l)
    DECL BOOL UnhookWindowsHookEx(l)
  ENDDLL

  RETVAL 1 /* everything o.k., DLL loaded

RETURN
'
PROCEDURE InstallHook()
  $EXPORT INSTALLHOOK,1

  lpShellProc% = @@SetWindowsHookEx(WH_SHELL%,_CB(2),_INSTANCE,0)

RETURN
'
PROCEDURE UninstallHook()
  $EXPORT UNINSTALLHOOK,2

  VOID @@UnhookWindowsHookEx(lpShellProc%)

RETURN
'
PROCEDURE ShellProc(nCode&,wParam&,lParam%)

  IF nCode& > 0
    IF nCode& = HSHELL_TASKMAN%
      RETVAL TRUE /** prevent Windows from calling it's own task list
    ELSE
      RETVAL @@CallNextHookEx(lpShellProc%,nCode&,wParam&,lParam%)
    ENDIF
  ELSE
    RETVAL @@CallNextHookEx(lpShellProc%,nCode&,wParam&,lParam%)
  ENDIF

RETURN

------------------------------------------------------------------------------------------
SAVE AS CALLHOOK.GFW:
------------------------------------------------------------------------------------------
// **************************************************************
//      GFA-BASIC for Windows Demonstration Program           
//      Copyright (c) 1997 by GFA Systemtechnik GmbH            
// --------------------------------------------------------------
//      You may copy, edit and distribute this program           
//      freely as long as you give credit and do not sell      
//      this demo as your own program.                          
//      You are allowed to use parts of the demo for your      
//      own needs if the result does not be similar to the      
//      original concerning outfit and functionality.             
//      The purpose of this program is to demonstrate           
//      the use of GFA-BASIC and the Windows API.              
//     Enhancements should be documented and up-             
//      loaded to the GFA BBS in Germany or to the GFA       
//      section in CompuServe. Both services offer you        
//      more examples, support and demo versions of          
//       GFA-BASIC.                                                   
// **************************************************************  
//      GFA BBS Germany, Moenchengladbach:                        
//              +49-2161-482460,24h,8N1,14400 bps, v.terbo       
//      GFA-BASIC fr Windows Demonstrations-Programm       
// **************************************************************  
//      GFA CompuServe                                                        
//              GO WINAPC, section GFA                                        
//              GFA CIS-ID: 75300,3224                                        
// **************************************************************
//      Last revision: 04/02/97 by S. Thomas, GFA Germany
// **************************************************************


DLL #1,"hookgfw.dll"
  DECL LONG InstallHook()
  DECL LONG UninstallHook()
ENDDLL

TITLEW #1,"Disable start menu"
OPENW #1,32768,32768,300,80,~15
CB WIN(1),0 TO -1, WndProc()

hShellTrayWnd& = FindWindow("Shell_TrayWnd",0)
IF hShellTrayWnd& <> 0 THEN DISABLEW hShellTrayWnd&

VOID @@InstallHook()
DO
  PEEKEVENT

  IF _Mess = WM_PAINT
    TEXT 10,10,"Start menu disabled, Ctrl-Esc disabled"
    TEXT 10,30,"Minimize function of this window disabled"
  ENDIF

UNTIL MENU(1) = 4

VOID @@UninstallHook()

CLOSEW #1
IF hShellTrayWnd& <> 0 THEN ENABLEW hShellTrayWnd&
FREEDLL 1
END



PROCEDURE WndProc(HWnd&,Mess&,wParam&,lParam%)

  IF Mess& = WM_SYSCOMMAND /* don't allow iconisation
    IF (wParam& & $FFF0) = SC_MINIMIZE THEN RETVAL 0
  ENDIF

RETURN


#: 97780 S12/GFA  (CIS:WINAPC)
    03-Apr-97  09:10:15
Sb: #97763-Hook DLL 
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

 >> But I found the following in Kyle Marsh's Windows Hook Sample
Application:

hhookMsgFilterHook = SetWindowsHookEx(...) UnhookWindowsHookEx(hhookMsgFilterHook); return ((int)CallNextHookEx(hhookMsgFilterHook, ...)

The h in front of hhookMsgFilterHook means handle because his long pointer variables all have lp in front of them?  Maybe this is another one of those cases where it doesn't matter what you declare ... it still works ... until you compile! ;)  <<

In C a variable which starts with h is used for handles, but who told you a handle should always be a 16-bit value ;-) ? If you read Kyle Marsh's article more carefully you'll find a describtion on the types used with SetWindowsHookEx at page 3. HHOOK is a 32-bit value.

Greetings, SH


#: 97781 S12/GFA  (CIS:WINAPC)
    03-Apr-97  09:10:15
Sb: #97764-Disable taskbar
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi james,

 >> Unfortunately, this code just disables the task bar as far as the mouse
is  concerned.  If your application's window has the focus, the Windows Logo Key  still makes the taskbar appear and the START popup menu portion of it will  still be enabled.   <<

You're correct I missed that. So we're back where we started. I figured out how to do it, however this requires a call to a 32-bit function SystemparametersInfo using thunking. I tried it without succes yet. I'll try it again.

Greetings, SH

BTW. I received my message containing the source code from NOSWITCH correctly. You said there were functions missing.


#: 97794 S12/GFA  (CIS:WINAPC)
    04-Apr-97  10:06:00
Sb: #97782-#Enter in Edit control
Fm: Sjouke Hamstra 100741,1036
To: Bob Springett 100772,452 (X)
Replies:   1

Hi Bob,

Thanks for the example, it works easier if I have the code you're actually working with.

I noticed the problem and I don't know what is happening (should have to do with local memory, somehow). However, since you want single line edit controls, I can provide you with another method to respond to the ENTER key. here it is.

$FOR style% = WS_SYSMENU | WS_CAPTION | WS_VISIBLE | DS_LOCALEDIT editstyle% = WS_BORDER | WS_TABSTOP  ' ******************************************ES_MULTILINE****** DIALOG #0,0,0,640,480,"",style%
  i& = 100
  FOR x& = 80 TO 530 STEP 50
    FOR y& = 20 TO 420 STEP 20
      CONTROL STR$(i&),i&,"edit",editstyle%,x&,y&,48,16
      INC i&
    NEXT y&
  NEXT x&
  DEFPUSHBUTTON "OK",IDOK,10,10,60,20
ENDDIALOG SHOWDIALOG #0

DO
  GETEVENT

  SWITCH MENU(1)

  CASE 30               // WM_COMMAND from control
    SWITCH _wParam
    CASE IDOK   // User has hit the ENTER key or Ok button

      hwndtest& = GetFocus()            // edit control has focus?
      id& = GetDlgCtrlID(hwndtest&)
      IF id& = _wParam
        finished! = TRUE
      ELSE IF id& >= 100 && id& <= 309       // yes, tab to next
        POSTMESSAGE _hWnd, WM_NEXTDLGCTL, 0, 0
      ENDIF

    OTHERWISE
      // other controls
    ENDSWITCH

  ENDSWITCH

UNTIL MENU(1) = 4 CLOSEDIALOG #0 END

Notice: hitting the ENTER key in a dialog box generates a WM_COMMAND for the DEFPUSHBUTTON, so you need to evaluate the WM_COMMAND for your(!) DEFPUSHBUTTON.

Greetings, SH


#: 97803 S12/GFA  (CIS:WINAPC)
    05-Apr-97  00:03:24
Sb: #97766-Disabling Alt-Tab Switch
Fm: James V. Schumacher 104166,2104
To: James V. Schumacher 104166,2104 (X)
Replies:   0

Sjouke, Fredrich, Sven ...

I can't begin to thank you for all the help you've given me in solving this problem.  

First of all, Sven, your shell hook proc works great.    I hadn't thought to try that particular type of hook.  I'm going to play around with it and may end up using it in my program if the simpler solution, discussed below, doesn't pan out.   In any case, it will help me learn more about Shell hooks, which I now see can be very useful too.

What I want to discuss in this post, however, is a solution that Fredrich suggested a while back that I overlooked at the time.  He suggested using the APL LockInput().   I finally tried it and it works like a charm in disabling not only the window logo key and ctrl-esc key combination but also the alt-tab combination!  The problem I've encountered, however, is that it seems to disable sndplaysound() calls too.  Could it be that the declaration is incorrect.  The last parameter is supposed to be BOOL.  Here is the code that demonstrates this problem.  Insert your own .wav file name.

OPENW #1
DLL #1,"user"
  DECL BOOL LockInput(w,w,w)
ENDDLL
DLL #5, "MMSYSTEM.dll"
  DECL WORD sndPlaySound(l,w)
ENDDLL
SND_FILENAME = &H20000 //load sound from filename
wavefilename$ = "goodwork.wav"
~^sndPlaySound(wavefilename$,SND_FILENAME) //plays ok
~^sndPlaySound(wavefilename$,SND_FILENAME) //plays ok
l! = ^LockInput(0,WIN(1),-1)
~^sndPlaySound(wavefilename$,SND_FILENAME) //does not play
DO
  GETEVENT
UNTIL MOUSEK = 2 //right button to quit
l! = ^LockInput(0,WIN(1),0)
~^sndPlaySound(wavefilename$,SND_FILENAME) //plays ok
FREEDLL 1
FREEDLL 5
CLOSEW #1

Hoping to "hear" from you!

James


#: 97804 S12/GFA  (CIS:WINAPC)
    05-Apr-97  03:38:22
Sb: Disabling Alt-Tab Switch
Fm: James V. Schumacher 104166,2104
To: All
Replies:   0

Hi,

I just want to add that by temporarily turning off  LockInput each time I call sndPlaySound(), I've got my program working without any apparent problems.  Just hope this continues to work when compiled and on Win3.1 systems!

James


#: 97806 S12/GFA  (CIS:WINAPC)
    05-Apr-97  10:21:07
Sb: #97802-Enter in Edit control
Fm: Sjouke Hamstra 100741,1036
To: Dale Bryant 73134,1500 (X)
Replies:   0

Hi Dale,

 >> In the edit box control example you posted which item is supposed to be
the  actual item selected by the user?

1. The item on which the enter key was last pressed. 2. The item highlighted after the enter key was last pressed.

I assumed it would be the item on whicch the enter key was pressed.   <<

When the edit control has the focus, i.e. the caret is in the edit control, and the ENTER key is pressed, the dialogbox handler (IsDialogmessage) generates a WM_COMMAND for the default push button. However, the focus is still on the edit control. Therfore, you should test where the focus is, when a WM_COMMAND for the default push button is generated. If there is no default push button, the dialog handler generates a WM_COMMAND for a virtual default push button and sets the wParam to IDOK.

Greetings, SH


#: 97808 S12/GFA  (CIS:WINAPC)
    05-Apr-97  14:10:04
Sb: #97803-Disabling Alt-Tab Switch
Fm: GFA Germany 75300,3224
To: James V. Schumacher 104166,2104
Replies:   0

James,

LockInput isn't a good way to disable input, because it disables each task without your own, so you can't run background processes like playing sound. LockInput has been set up for debugging purposes, and is usually used by a debugger, not by normal programs.
You should do it another way, because if using LockInput the currently running tasks that become deactivated now can't process their messages (sometimes they can...), and if you unlock the system again, they will process them all at one time which could result in flickering, unstable system status etc.

BTW: The declaration of LockInput is well done.

Greetings

Sven, GFA


#: 97837 S12/GFA  (CIS:WINAPC)
    08-Apr-97  09:38:10
Sb: #97827-Disabling Alt-Tab Switch
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

 >> Is there anything equivalent in WIN32 to LockInput or is that further
motivation to use the shellhook approach and some unknown (as yet) alt-tab disabler?  Speaking of which, the copy of your noswitch.gfw that I downloaded from compuserve was clearly missing several routines.  Could you possibly email me a copy directly.  It probably has the clue I need to disable the alt- tab keys.  <<

Ofcourse, I will send you the NOSWITCH source code. However, it is a DLL (you hate to add another one) as Sven's shellhook. As a matter of fact, to implement the task-switcher prevention method, the code should be extended by adding Sven's shellhook. Although, I've seen a different appoach of diabling the task switcher using SystemParametersInfo, the method Sven suggested is definetly the best approach! This is why MS added the ShellHook in the first place. Tip: you could easily put the shellhook code into the BMP.DLL, preventing you from adding a second DLL.

Greetings, SH


#: 97858 S12/GFA  (CIS:WINAPC)
    09-Apr-97  13:54:11
Sb: Calling 32 APIs
Fm: Sjouke Hamstra 100741,1036
To: ALL
Replies:   0

To All

I have uploaded the file GFA32API.ZIP containing documentation and code on how to call Win32 API functions from a 16-bit GFABASIC application. I was forced to do so because of James; I needed the 32-bit SystemParametersInfo to see if I could disable the Windows Logo key ;).

Well it evoleved in GFA32API.DLL which contains the actual calls to the 32 API functions. It can be extended with the API calls you need very easily. Just take a look.

Greetings, SH


#: 97885 S12/GFA  (CIS:WINAPC)
    11-Apr-97  02:35:27
Sb: #Disabling Alt-Tab Switch
Fm: James V. Schumacher 104166,2104
To: All
Replies:   1

Sven and Sjouke,

Sjouke's noswitch.gfw includes the following window procedure code:

PROCEDURE WndProc(hWnd,Mess,wParam,lParam%)
  SWITCH Mess
  CASE WM_SYSCOMMAND
    SWITCH (wParam)
    CASE SC_NEXTWINDOW, SC_PREVWINDOW, SC_TASKLIST
      RETVAL 0
    CASE SC_MINIMIZE            /* we don't want to be minimized at this point */
      IF (!EnabledTaskSwitch!)  /* if the task switch is disabled, then we return */
        RETVAL 0
      ENDIF
    ENDSWITCH
<snip>
RETURN

whereas Sven's shellhock code has this window procedure:

PROCEDURE WndProc(HWnd&,Mess&,wParam&,lParam%)
  IF Mess& = WM_SYSCOMMAND /* don't allow iconisation
    IF (wParam& & $FFF0) = SC_MINIMIZE THEN RETVAL 0
  ENDIF
RETURN

Notice that Sjouke's code is supposed to return RETVAL 0 if wparam = SC_MINIMIZE while Sven's does so only if (wparam & $FFF0) = SC_MINIMIZE.  Testing the two, I find that Sven's code works but Sjouke's doesn't.  So, my question is what is $FFF0? 

Also, according to Microsoft's NOSWITCH documentation, Sjouke's

  SWITCH Mess
  CASE WM_SYSCOMMAND
    SWITCH (wParam)
    CASE SC_NEXTWINDOW, SC_PREVWINDOW, SC_TASKLIST
      RETVAL 0

code is supposed to deactivate the alt-tab fast task switcher as long as the window is maximized.  However, in testing Sjouke code, I find that when alt-tab is pressed, no WM_SYSCOMMAND message is received by the window procedure so this code is never used.  Yet, Microsoft's NOSWITCH.EXE application works as advertized.   Could it be that some value also has to be &ed with MESS for the code to work and what about CASE SC_NEXTWINDOW, SC_PREVWINDOW, SC_TASKLIST? 

Still gnawing at this problem,

James


#: 97892 S12/GFA  (CIS:WINAPC)
    11-Apr-97  10:13:07
Sb: #97885-Disabling Alt-Tab Switch
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James,

 >> Sjouke's noswitch.gfw includes the following window procedure code: <<

It isn't actually mine, it's a (very quickly done) translation from MS NOSWITCH.C code to GFABasic. I provided it, so you had a starting point, I never tested it ;)

IMHO, you shoul act as follows. The NOSWITCH code is intended for Windows 3.1, the shellhook code from Sven is intended for WIN32 systems. You should merge both methods and execute the appropriate method on each system.

SetSysModalWindow() works as a treat..., as long as you use a maximized window, all other window functions are disbaled, however that's exactly whta you want, isn't? The SetSysModalWindow function is not implemented in the Win32 API. The new input model does not allow for System Modal windows. Porting your application to Win32 next year will give you problems again. However, who lives then, worries then.

I'm glad you found a solution.

Greetings, SH


#: 97890 S12/GFA  (CIS:WINAPC)
    11-Apr-97  08:02:23
Sb: Disabling TaskSwitchers!
Fm: James V. Schumacher 104166,2104
To: ALL
Replies:   0

YIPPEE !!!!!

I'm excited because I have the solution to the problem of disabling the windows logo key, ctrl-esc task switcher and the alt-tab task switcher.  

A while back Fredrich suggested that I try the API SetSysModalWindow() but I had my mind on hooks at the time and, I'm ashamed to admit, overlooked it.  This afternoon, I was rereading all the posts on this subject and I noticed his suggestion.  I tried it and it is just  what I have been looking for all along!  THANK YOU Fredrich!!!

I can't believe how simple the answer is!  As soon as I make my window active, I call SetSysModalWindow().  That alone disable all the task switchers.   Then when the password window that I use to get out of this window is opened, I SetSysModalWindow to it.  When the password window is then closed, the SetSysModalWindow state is canceled and things return to normal with the task switchers again enabled.  Furthermore, since this is a Win3.1 call that I'm using on a Win95 system, I'm pretty sure it will work on both platforms.

I want to thank everyone who has contributed to this thread, especially Sjouke, Sven and Fredrich.  Despite the fact that I won't need to use a hook, I have learned a great deal from this discussion.  I am positive that hooks will be very useful in future applications.  In fact, I still would like answers to the couple of questions I posted today even though they are no longer needed to get my program to market.  In particular I want to know why the $FFF0 was needed in the shell window procedure.

Now, all that remains is to finish up adapting my manual to Windows and create the installer files.  I can't thank you all enough for getting me to this point ... its been a frustrating journey.   After I get the product out, I'll start on my next application, first creating it on the Mac, then porting it with my translator, which will be much improved based on all I've learned the last 6 months, to GFABasic on the PC.

YES!!!

James


#: 97902 S12/GFA  (CIS:WINAPC)
    12-Apr-97  17:40:21
Sb: #97885-Disabling Alt-Tab Switch
Fm: GFA Germany 75300,3224
To: James V. Schumacher 104166,2104
Replies:   0

James,

glad to hear that you have found a solution for your problem.
And to let you become really happy, your last outstanding question:

<<Notice that Sjouke's code is supposed to return RETVAL 0 if wparam = SC_MINIMIZE while Sven's does so only if (wparam & $FFF0) = SC_MINIMIZE.  Testing the two, I find that Sven's code works but Sjouke's doesn't.  So, my question is what is $FFF0? <<

The WM_SYSCOMMAND has a special coding for the word parameter (received in _wParam). To handle it with the SC_xxxx constants declared in Windows.h (e.g. SC_MINIMIZE), you always have to do a bitwise AND with $FFF0, that's all. Only some bit rotation...
Otherwise you will receive a WM_SYSCOMMAND message for minimization as well, but the wParam does not contain the declaed SC_xxxx constants but another value. 
Why? .....   there is no answer that makes sense....

Regards

Sven, GFA


#: 97932 S12/GFA  (CIS:WINAPC)
    15-Apr-97  17:32:13
Sb: #97902-Disabling Alt-Tab Switch
Fm: James V. Schumacher 104166,2104
To: GFA Germany 75300,3224
Replies:   0

>> The WM_SYSCOMMAND has a special coding for the word parameter (received in _wParam).  To handle it with the SC_xxxx constants declared in Windows.h (e.g. SC_MINIMIZE), you always have to do a bitwise AND with $FFF0, that's all. <<

How curious!!  Are there any other messages that receive this special treatment?  Also, where is this documented ... in GFABasic literature?

James


#: 97943 S12/GFA  (CIS:WINAPC)
    16-Apr-97  07:34:19
Sb: #97891-Printing
Fm: Bob Springett 100772,452
To: Sjouke Hamstra 100741,1036
Replies:   0

Sjouke,
You may remember that I said when printing via the printer directly instead of via the 
Windows hdc multiple page printing,whilst initial response was faster it was corrupted
and didn't finish.
I have found that removing the colon from 'OPEN "O",#10,"LPT1:"' seems to resolve this
problem.
Printing this way keeps the printer moving all the time once it has started, whereas printing via hdc is slower.
Regards
Bob


#: 97941 S12/GFA  (CIS:WINAPC)
    16-Apr-97  04:45:13
Sb: Upper Case DLGDIRLIST?
Fm: James V. Schumacher 104166,2104
To: ALL
Replies:   0

Hi,

Just realized I have another problem.  I'm using the following code to load a hidden listbox with the names of the files in a directory. Later, I'm retrieving a name from the listbox. The problem is that the names in the listbox appear to all be lower case, despite the fact that some of the filenames are upper case.  Is this due to the way DlgDirList() works?   I need to distinguish between upper and lower case letters in filenames.  Is there something I can change here or something that can be done?

style% = WS_CHILDWINDOW
hpicturefilenamelistbox& = CreateWindow("LISTBOX","",style%,0,0,_X,_Y,WIN(WIN()),listID&,_INSTANCE,0)
'load listbox with filenames
 folderPath$ = gPictureFolderPath$ + CHR$(0)
f! = DlgDirList(WIN(WIN()),V:folderPath$,listID&,0,0)
<snip>
~SendMessage(hpicturefilenamelistbox&,LB_GETTEXT,fileNum& - 1,V:fileName$)

Thanks,

James


#: 97944 S12/GFA  (CIS:WINAPC)
    16-Apr-97  08:55:10
Sb: Upper Case DLGDIRLIST?
Fm: James V. Schumacher 104166,2104
To: ALL
Replies:   0

Hi,

I just downloaded Roland Walter's examples using the 32 bit FINDFIRSTFILE, FINDNEXTFILE and CLOSEFILE functions.  On my Win95 system, they seem to distinguish between upper and lower case letters.  So ... is my problem with DLGDIRLIST simply that the Win3.1 directory structure does not distinguish whether filenames have upper or lower case letters?  Will my Win3.1 users even be able to name files with both upper and lower case letters?   I have to say that all the books I have showing directories in Win3.1 show all lower case or all upper case filenames.

James


#: 97946 S12/GFA  (CIS:WINAPC)
    16-Apr-97  14:57:08
Sb: Listbox  la Win95?
Fm: Marco A. Kummer 100341,411
To: all
Replies:   0

Hi!
Is there a way to include a Listbox in GFA Basic like modern win95 applications have them: E.g. a listbox that is divided into two or three colums and the user can change the size of each column. (just like in WinZIP)
How could I do that?

Thanks for your help!
-Marco


#: 97957 S12/GFA  (CIS:WINAPC)
    17-Apr-97  09:54:01
Sb: #97946-Listbox  la Win95?
Fm: Sjouke Hamstra 100741,1036
To: Marco A. Kummer 100341,411
Replies:   0

Hi Marco,

 >> Is there a way to include a Listbox in GFA Basic like modern win95
applications have them: E.g. a listbox that is divided into two or three colums and the user can change the size of each column. (just like in WinZIP) How could I do that?  <<

Displaying a multicolumn listbox isn't difficult, the interface to dynamically resize columns involves a bit more coding. To display a multicolumn listbox you can add the LBS_MULTICOLUMN style, however I assume that's not what you want. So, you'll need an ownerdrawn listbox, and do the drawing yourself. Also you must subclass the listbox and handle the mouse messages.


#: 97988 S12/GFA  (CIS:WINAPC)
    18-Apr-97  09:53:25
Sb: #97960-#Alert/Message boxes
Fm: Sjouke Hamstra 100741,1036
To: Andrew Risely 100667,1620 (X)
Replies:   1

Hi Andrew,

 >> In summary, how does the GFA ALERT procedure obtain the correct window
handle  every time.  <<

One of two ways:

hActiveGFAWIN = WIN(WIN())

or when you respond to a message the handle of the window the message was sent to:

hActiveGFAWIN = _hWnd   (best way to go)

Greetings, SH


#: 98013 S12/GFA  (CIS:WINAPC)
    19-Apr-97  11:37:02
Sb: #97993-Alert/Message boxes
Fm: Sjouke Hamstra 100741,1036
To: Andrew Risely 100667,1620
Replies:   0

 >> I have tried this but if a dialog is diaplayed over the top of the window
the  dialog handle is not returned, instead the already disabled window handle is  returned.  <<

I don't understand; usually you would retrieve the handle of the parent _before_ displaying a dialog box. This is usually done when processing some kind of message (WM_COMMAND), the handle specifed in _hWnd specifies the window the message is posted to. Windows application are constructed around message handling, so you must have a windows handle at any time. If however you use a special kind of dialog box within a DLL, you might use NULL for the window handle.

Greetings, SH


#: 98040 S12/GFA  (CIS:WINAPC)
    21-Apr-97  13:59:27
Sb: #98027-Calling 32 APIs
Fm: John Findlay 100130,1771
To: Sjouke Hamstra 100741,1036
Replies:   0

>> Have you experimented with it? <<

A bit! I've added stuff to read the long file names etc. It works fine. Now all we need is someone to add a few hundred WIN32 API's and we'll be swinging. :-)

Here's the extra code to add to Sjouke's DLL and an example for anyone who's interested.

Add this to Sjouke's 'gfa32api.dll' and recompile;

==================================================
PROCEDURE FindFirstFile(lpszSearchFile%, lpffd%)
  $EXPORT FindFirstFile
  TRY
    RETVAL P:(lpf32%)(L:lpszSearchFile%,L:lpffd%,L:^GetProcAddress32W(hkernel32%,"FindFirstFileA"),L:%11,L:2)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE FindNextFile(hFindFile%, lpffd%)
  $EXPORT FindNextFile
  TRY
    RETVAL P:(lpf32%)(L:hFindFile%,L:lpffd%,L:^GetProcAddress32W(hkernel32%,"FindNextFileA"),L:%1,L:2)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE FindClose(hFindFile%)
  $EXPORT FindClose
  TRY
    RETVAL P:(lpf32%)(L:hFindFile%,L:lpffd%,L:^GetProcAddress32W(hkernel32%,"FindCloseA"),L:%1,L:1)
  CATCH
  RETVAL ERR
RETURN
==================================================

And here's the example;

==================================================
@Init()

OPENW #1,0,0,800,600,-1

@Examples()

ON MENU MESSAGE GOSUB HandleMessage
DO
  SLEEP
UNTIL MENU(1) = 4
CLOSEW #1
FREEDLL 11
END

PROCEDURE HandleMessage
  SWITCH MENU(1)
  CASE 21
  ENDSWITCH
RETURN

PROCEDURE Examples()

  ' lpszSearchFile%    Points to a null-terminated string that specifies a valid
  ' directory or path and filename, which can contain wildcard characters (* and ?).

  ' lpffd%      Points to the WIN32_FIND_DATA structure that receives information
  ' about the found file or subdirectory. The structure can be used in subsequent
  ' calls to the FindNextFile or FindClose functions to refer to the file or subdirector.

  pathStr$ = "c:\*.*" + CHR$(0)
  lpszSearchFile% = V:pathStr$
  lpffd% = V:finddat32.

  hFindFile% = ^FindFirstFile(lpszSearchFile%, lpffd%)
  WHILE hFindFile%
    a$=SPACE$(80)
    SELECT finddat32.dwFileAttributes
    CASE FILE_ATTRIBUTE_DIRECTORY%
      MID$(a$,1)="<DIR>"
    CASE FILE_ATTRIBUTE_SYSTEM%
      MID$(a$,1)="<SYS>"
    CASE FILE_ATTRIBUTE_READONLY%
      MID$(a$,1)="<READ>"
    CASE FILE_ATTRIBUTE_ARCHIVE%
      MID$(a$,1)="<ARCH>"
    CASE FILE_ATTRIBUTE_HIDDEN%
      MID$(a$,1)="<HID>"
    CASE FILE_ATTRIBUTE_TEMPORARY%
      MID$(a$,1)="<TEMP>"
    CASE FILE_ATTRIBUTE_NORMAL%
      MID$(a$,1)="<NORM>"
    ENDSELECT
    MID$(a$,12)=finddat32.cFileName$
    e% = ^FindNextFile(hFindFile%, lpffd%)
    PRINT a$, e%
    EXIT IF !e%
  WEND
  e% = ^FindClose(hFindFile%)
RETURN
PROCEDURE Init()

  DLL #11,"E:\TEXT\GFA32API.DLL"

    // KERNEL32 functions
    DECL DWORD GetDriveType(l)                    // lpszRootPathName
    DECL DWORD GetLogicalDrives()
    DECL DWORD GetFullPathName(l,l,l,l)           // lpszFile, cchPath, lpszPath, ppszFilePar
    DECL DWORD GetLogicalDriveStrings(l,l)        // cchBuffer, lpszBuffer
    DECL DWORD FindFirstFile(l,l)                 // lpszSearchFile, lpffd
    DECL DWORD FindNextFile(l,l)                  // hFindFile, lpffd
    DECL DWORD FindClose(l)                       // hFindFile

    // GDI32 functions
    DECL DWORD GetCurrentObject(l,l)              // hdc, uObjectType
    DECL BOOL  PlgBlt(l,l,l,l,l,l,l,l,l,l)        // hdcDest, lpPoint, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hbmMask, xMask,yMask

    // USER32 functions
    DECL DWORD SystemParametersInfo(l,l,l,l)      // wAction, wParam, lpvParam, fUpdateProfile

  ENDDLL

  ' Data Structure for WIN32

  TYPE FindFileDataWIN32:
  - DWORD dwFileAttributes
  '=>>FILETIME ftCreationTime (32 bits)
  - DWORD dwLowCreationTime
  - DWORD dwHighCreationTime
  '=>>FILETIME ftLastAccessTime (32 bits)
  - DWORD dwLowLastAccessTime
  - DWORD dwHighLastAccessTime
  '=>>FILETIME ftLastWriteTime (32 bits)
  - DWORD dwLowLastWriteTime
  - DWORD dwHighLastWriteTime

  - DWORD     nFileSizeHigh
  - DWORD     nFileSizeLow
  - DWORD     dwReserved0
  - DWORD     dwReserved1
  - CHAR*80   cFileName$                // Max size 260 chars
  - CHAR*14   cAlternateFileName$
  ENDTYPE
  FindFileDataWIN32: finddat32.

  ' dwFileAttributes

  FILE_ATTRIBUTE_ARCHIVE% = $20 // The file is an archive file. Applications use
  '                             // this flag to mark files for backup or removal.

  FILE_ATTRIBUTE_DIRECTORY% = $10 // The file is a directory.

  FILE_ATTRIBUTE_HIDDEN% = $02 // The file is hidden. It is not included in an
  '                            // ordinary directory listing.
  FILE_ATTRIBUTE_NORMAL% = $80 // The file has no other attributes set. This attribute
  '                            // is valid only if used alone.

  FILE_ATTRIBUTE_READONLY% = $01 // The file is a read-only file. Applications can
  '                              // read the file but cannot write to it or delete it.

  FILE_ATTRIBUTE_SYSTEM% = $04 // The file is part of or is used exclusively
  '                            // by the operating system

  FILE_ATTRIBUTE_TEMPORARY% = $100 // The file is a temporary file. Applications can
  '                                // write to the file only if absolutely necessary.
  '                                // Most of the file's data remains in memory without
  '                                // being flushed to the media because the file will
  '                                // soon be deleted.

  ' ftCreationTime
  '     Specifies the time the file was created. A value of 0,0 indicates
  '     that the file system containing the file does not support this time field.

  ' ftLastAccessTime
  '     Specifies the time that the file was last accessed. A value of 0,0 indicates
  '     that the file system containing the file does not support this time field.

  ' ftLastWriteTime
  '     Specifies the time that the file was last written to. All file systems
  '     support this time field.

  ' nFileSizeHigh
  '     Specifies the high-order word of the file size, in bytes.

  ' nFileSizeLow
  '     Specifies the low-order word of the file size, in bytes.

  ' cFileName
  '     Specifies a null-terminated string that is the name of the file.

  ' cAlternateFileName
  '     Specifies a null-terminated string that is an alternative name of the file,
  '     in the 8.3 (filename.ext) format.


RETURN


#: 98071 S12/GFA  (CIS:WINAPC)
    23-Apr-97  10:07:05
Sb: #98055-Alert/Message boxes
Fm: Sjouke Hamstra 100741,1036
To: Andrew Risely 100667,1620
Replies:   0

Hi Andrew,

If I understand correctly (which I doubt), your sequence of commands is as follows:

Dialog("printing...") STARTDOC DoPrinting ENDDOC

And now you want to add a second dialog box within the STARTDOC/ENDDOC commands, thereby disabling the previous Dialog box/and or main window? How about this:

Dialog(1,"Printng...") DISABLEW #WIN() STARTDOC Dialog(2,Temporary) DISABLEW DLG(1) DoPrinting ENDDOC ENABLEW DLG(1) CLOSEDIALOG 2 ENABLEW #WIN() CLOSEDIALOG 1

If this doesn't reflect the actual situation, please post the printing code and let me see what exactly you're doing.

>>PS I have picked up on some chatter regarding your book.  Is this a new book, if so how do I obtain it in the UK and how much.<<

It's available for quite some time now. You can order it from GFA Germany directly or from Marko Software in the Netherlands. There is a text file in the library (GFABOOK.TXT) that explains how to order from Marko Software. To order from GFA please send them an e-mail message.

Greetings, SH


#: 98067 S12/GFA  (CIS:WINAPC)
    23-Apr-97  09:11:07
Sb: #98040-#Calling 32 APIs
Fm: John Findlay 100130,1771
To: John Findlay 100130,1771 (X)
Replies:   1

Dear All,

There were a few mistakes in the code that I sent in my last message, specifically the API call FindClose() did not work; sorry! I have made a few other changes as well.

If you find any more mistakes let me know;

This code to be added to Sjouke's "GFA32API.DLL";

==================================================
PROCEDURE FindFirstFile(lpszSearchFile%, lpffd%)
  $EXPORT FindFirstFile
  TRY
    RETVAL P:(lpf32%)(L:lpszSearchFile%,L:lpffd%,L:^GetProcAddress32W(hkernel32%,"FindFirstFileA"),L:%11,L:2)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE FindNextFile(hFindFile&, lpffd%)
  $EXPORT FindNextFile
  TRY
    RETVAL P:(lpf32%)(hFindFile&,L:lpffd%,L:^GetProcAddress32W(hkernel32%,"FindNextFileA"),L:%1,L:2)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE FindClose(hFindFile&)
  $EXPORT FindClose
  TRY
    RETVAL P:(lpf32%)(hFindFile&,L:^GetProcAddress32W(hkernel32%,"FindClose"),L:%0,L:1)
  CATCH
  RETVAL ERR
RETURN
==================================================

And this is the example;

==================================================
@Init()

OPENW #1,0,0,600,500,~15

@Examples()

ON MENU MESSAGE GOSUB HandleMessage

DO
  SLEEP
UNTIL MENU(1) = 4

CLOSEW #1
FREEDLL 11
END

PROCEDURE HandleMessage
  SWITCH MENU(1)
  CASE 21
  ENDSWITCH
RETURN
PROCEDURE Examples()

  ' lpszSearchFile%    Points to a null-terminated string that specifies a valid
  ' directory or path and filename, which can contain wildcard characters (* and ?).

  ' lpffd%      Points to the WIN32_FIND_DATA structure that receives information
  ' about the found file or subdirectory. The structure can be used in subsequent
  ' calls to the FindNextFile or FindClose functions to refer to the file or subdirector.

  pathStr$ = "c:\*.*" + CHR$(0)
  lpszSearchFile% = V:pathStr$
  lpffd% = V:finddat32.

  hFindFile& = ^FindFirstFile(lpszSearchFile%, lpffd%)
  @EvalFileData()

  WHILE ^FindNextFile(hFindFile&, lpffd%)
    @EvalFileData()
  WEND

  e| = ^FindClose(hFindFile&)
  PRINT e|
RETURN
PROCEDURE EvalFileData()
  q$=""
  IF BTST(finddat32.dwFileAttributes,ATT_DIRECTORY|) THEN q$ = "<Dir>"
  IF BTST(finddat32.dwFileAttributes,ATT_ARCHIVE|)   THEN q$ = q$ + "a"
  IF BTST(finddat32.dwFileAttributes,ATT_HIDDEN|)    THEN q$ = q$ + "h"
  IF BTST(finddat32.dwFileAttributes,ATT_NORMAL|)    THEN q$ = q$ + "n"
  IF BTST(finddat32.dwFileAttributes,ATT_READONLY|)  THEN q$ = q$ + "r"
  IF BTST(finddat32.dwFileAttributes,ATT_SYSTEM|)    THEN q$ = q$ + "s"
  IF BTST(finddat32.dwFileAttributes,ATT_TEMPORARY|) THEN q$ = q$ + "t"

  PRINT q$,finddat32.cFileName$
RETURN
PROCEDURE Init()

  DLL #11,"GFA32API.DLL"

    // KERNEL32 functions
    DECL DWORD GetDriveType(l)                    // lpszRootPathName
    DECL DWORD GetLogicalDrives()
    DECL DWORD GetFullPathName(l,l,l,l)           // lpszFile, cchPath, lpszPath, ppszFilePar
    DECL DWORD GetLogicalDriveStrings(l,l)        // cchBuffer, lpszBuffer
    DECL WORD  FindFirstFile(l,l)                 // lpszSearchFile, lpffd
    DECL BOOL  FindNextFile(w,l)                  // hFindFile, lpffd
    DECL BOOL  FindClose(w)                       // hFindFile

    // GDI32 functions
    DECL DWORD GetCurrentObject(l,l)              // hdc, uObjectType
    DECL BOOL  PlgBlt(l,l,l,l,l,l,l,l,l,l)        // hdcDest, lpPoint, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hbmMask, xMask,yMask

    // USER32 functions
    DECL DWORD SystemParametersInfo(l,l,l,l)      // wAction, wParam, lpvParam, fUpdateProfile

  ENDDLL

  ' Data Structure for WIN32

  TYPE FindFileDataWIN32:
  - DWORD dwFileAttributes
  ' FILETIME ftCreationTime (32 bits)
  - DWORD dwLowCreationTime
  - DWORD dwHighCreationTime
  ' FILETIME ftLastAccessTime (32 bits)
  - DWORD dwLowLastAccessTime
  - DWORD dwHighLastAccessTime
  ' FILETIME ftLastWriteTime (32 bits)
  - DWORD dwLowLastWriteTime
  - DWORD dwHighLastWriteTime

  - DWORD     nFileSizeHigh
  - DWORD     nFileSizeLow
  - DWORD     dwReserved0
  - DWORD     dwReserved1
  - CHAR*80   cFileName$                // Max size 260 chars
  - CHAR*14   cAlternateFileName$
  ENDTYPE
  FindFileDataWIN32: finddat32.

  ' Used bitwise on finddat32.dwFileAttributes

  ATT_ARCHIVE|   = 5    // The file is an archive file.
  ATT_DIRECTORY| = 4    // The file is a directory.
  ATT_HIDDEN|    = 1    // The file is hidden.
  ATT_NORMAL|    = 7    // The file has no other attributes set.
  ATT_READONLY|  = 0    // The file is a read-only file.
  ATT_SYSTEM|    = 2    // The file is a system file.
  ATT_TEMPORARY| = 8    // The file is a temporary file.

  ' ftCreationTime
  '     Specifies the time the file was created. A value of 0,0 indicates
  '     that the file system containing the file does not support this time field.
  ' ftLastAccessTime
  '     Specifies the time that the file was last accessed. A value of 0,0 indicates
  '     that the file system containing the file does not support this time field.
  ' ftLastWriteTime
  '     Specifies the time that the file was last written to. All file systems
  '     support this time field.
  ' nFileSizeHigh
  '     Specifies the high-order word of the file size, in bytes.
  ' nFileSizeLow
  '     Specifies the low-order word of the file size, in bytes.
  ' cFileName$
  '     Specifies a null-terminated string that is the name of the file.
  ' cAlternateFileName$
  '     Specifies a null-terminated string that is an alternative name of the file,
  '     in the 8.3 (filename.ext) format.
RETURN


#: 98075 S12/GFA  (CIS:WINAPC)
    23-Apr-97  10:24:06
Sb: #98067-Calling 32 APIs
Fm: Sjouke Hamstra 100741,1036
To: John Findlay 100130,1771 (X)
Replies:   0

Hi John

 >> There were a few mistakes in the code that I sent in my last message,
specifically the API call FindClose() did not work; sorry! I have made a few other changes as well. If you find any more mistakes let me know;  <<

John, don't forget all Win32 API functions take long parameters! So, you made some errors, here is your source code which I corrected.

Greetings, SH

================================================= Add to the GFA32API

PROCEDURE FindFirstFile(lpszSearchFile, lpffd)
  $EXPORT FindFirstFile
  TRY
    RETVAL
P:(lpf32)(L:lpszSearchFile,L:lpffd,L:^GetProcAddress32W(hkernel32,"FindFirstF ileA"),L:%11,L:2)
  CATCH
  RETVAL ERR
RETURN PROCEDURE FindNextFile(hFindFile, lpffd)
  $EXPORT FindNextFile
  TRY
    RETVAL
P:(lpf32)(L:hFindFile,L:lpffd,L:^GetProcAddress32W(hkernel32,"FindNextFileA") ,L:%01,L:2)
  CATCH
  RETVAL ERR
RETURN PROCEDURE FindClose(hFindFile)
  $EXPORT FindClose
  TRY
    RETVAL
P:(lpf32)(L:hFindFile,L:lpffd,L:^GetProcAddress32W(hkernel32,"FindCloseA"),L: %0,L:1)
  CATCH
  RETVAL ERR
RETURN

======================================================== @Init() OPENW #1,0,0,600,500,~15 @Examples() ON MENU MESSAGE GOSUB HandleMessage DO
  SLEEP
UNTIL MENU(1) = 4 CLOSEW #1 FREEDLL 11 END

PROCEDURE HandleMessage
  SWITCH MENU(1)
  CASE 21
  ENDSWITCH
RETURN PROCEDURE Examples()

  ' lpszSearchFile%    Points to a null-terminated string that specifies a
valid
  ' directory or path and filename, which can contain wildcard characters (*
and ?).

  ' lpffd%      Points to the WIN32_FIND_DATA structure that receives
information
  ' about the found file or subdirectory. The structure can be used in
subsequent
  ' calls to the FindNextFile or FindClose functions to refer to the file or
subdirector.

  pathStr$ = "c:\*.*" + CHR$(0)
  lpszSearchFile% = V:pathStr$
  lpffd% = V:finddat32.

  hFindFile% = ^FindFirstFile(lpszSearchFile%, lpffd%)
  @EvalFileData()

  WHILE ^FindNextFile(hFindFile%, lpffd%)
    @EvalFileData()
  WEND

  e| = ^FindClose(hFindFile%)
  PRINT e|
RETURN

PROCEDURE EvalFileData()
  q$ = ""
  IF BTST(finddat32.dwFileAttributes,ATT_DIRECTORY|) THEN q$ = "<Dir>"
  IF BTST(finddat32.dwFileAttributes,ATT_ARCHIVE|)   THEN q$ = q$ + "a"
  IF BTST(finddat32.dwFileAttributes,ATT_HIDDEN|)    THEN q$ = q$ + "h"
  IF BTST(finddat32.dwFileAttributes,ATT_NORMAL|)    THEN q$ = q$ + "n"
  IF BTST(finddat32.dwFileAttributes,ATT_READONLY|)  THEN q$ = q$ + "r"
  IF BTST(finddat32.dwFileAttributes,ATT_SYSTEM|)    THEN q$ = q$ + "s"
  IF BTST(finddat32.dwFileAttributes,ATT_TEMPORARY|) THEN q$ = q$ + "t"

  PRINT q$,finddat32.cFileName$
RETURN

PROCEDURE Init()

  DLL #11,"GFA32API.DLL"

    // KERNEL32 functions
    DECL DWORD GetDriveType(l)                    // lpszRootPathName
    DECL DWORD GetLogicalDrives()
    DECL DWORD GetFullPathName(l,l,l,l)           // lpszFile, cchPath,
lpszPath, ppszFilePar
    DECL DWORD GetLogicalDriveStrings(l,l)        // cchBuffer, lpszBuffer
    DECL LONG  FindFirstFile(l,l)                 // lpszSearchFile, lpffd
    DECL BOOL  FindNextFile(l,l)                  // hFindFile, lpffd
    DECL BOOL  FindClose(l)                       // hFindFile

    // GDI32 functions
    DECL DWORD GetCurrentObject(l,l)              // hdc, uObjectType
    DECL BOOL  PlgBlt(l,l,l,l,l,l,l,l,l,l)        // hdcDest, lpPoint,
hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hbmMask, xMask,yMask

    // USER32 functions
    DECL DWORD SystemParametersInfo(l,l,l,l)      // wAction, wParam,
lpvParam, fUpdateProfile

  ENDDLL

  ' Data Structure for WIN32

  TYPE FindFileDataWIN32:
  - DWORD dwFileAttributes
  ' FILETIME ftCreationTime (32 bits)
  - DWORD dwLowCreationTime
  - DWORD dwHighCreationTime
  ' FILETIME ftLastAccessTime (32 bits)
  - DWORD dwLowLastAccessTime
  - DWORD dwHighLastAccessTime
  ' FILETIME ftLastWriteTime (32 bits)
  - DWORD dwLowLastWriteTime
  - DWORD dwHighLastWriteTime

  - DWORD     nFileSizeHigh
  - DWORD     nFileSizeLow
  - DWORD     dwReserved0
  - DWORD     dwReserved1
  - CHAR*80   cFileName$                // Max size 260 chars
  - CHAR*14   cAlternateFileName$
  ENDTYPE
  FindFileDataWIN32: finddat32.

  ' Used bitwise on finddat32.dwFileAttributes

  ATT_ARCHIVE|   = 5    // The file is an archive file.
  ATT_DIRECTORY| = 4    // The file is a directory.
  ATT_HIDDEN|    = 1    // The file is hidden.
  ATT_NORMAL|    = 7    // The file has no other attributes set.
  ATT_READONLY|  = 0    // The file is a read-only file.
  ATT_SYSTEM|    = 2    // The file is a system file.
  ATT_TEMPORARY| = 8    // The file is a temporary file.

  ' ftCreationTime
  '     Specifies the time the file was created. A value of 0,0 indicates
  '     that the file system containing the file does not support this time
field.
  ' ftLastAccessTime
  '     Specifies the time that the file was last accessed. A value of 0,0
indicates
  '     that the file system containing the file does not support this time
field.
  ' ftLastWriteTime
  '     Specifies the time that the file was last written to. All file
systems
  '     support this time field.
  ' nFileSizeHigh
  '     Specifies the high-order word of the file size, in bytes.
  ' nFileSizeLow
  '     Specifies the low-order word of the file size, in bytes.
  ' cFileName$
  '     Specifies a null-terminated string that is the name of the file.
  ' cAlternateFileName$
  '     Specifies a null-terminated string that is an alternative name of the
file,
  '     in the 8.3 (filename.ext) format.
RETURN


#: 98052 S12/GFA  (CIS:WINAPC)
    22-Apr-97  21:11:00
Sb: #98027-#Calling 32 APIs
Fm: James V. Schumacher 104166,2104
To: Sjouke Hamstra 100741,1036 (X)
Replies:   1

Hi Sjouke,

I just downloaded your GFA32API.ZIP.  Thank you for all the effort it obviously entailed to produce.  I really look forward to seeing your next book which I presume this may be for.  My question is whether this is provided as an example of the only "safe" way to use 32 bit routines in a 16 bit program ... or is the purpose just to allow one to use 32bit DLLs more easily?   The reason I ask is that I am already using several 32bit DLL's in my 16 bit application (with, of course, a check to make sure the routines are only called if it is a Windows95 computer).   They seem to work ok.

Also, just as a warning to others, I've again encountered problems because I incorrectly declared some 32 bit routine parameter handles as WORD rather than LONG.   Specifically, I found examples of FindFirstFile, FindNextFile and CloseFile being used in Roland Walters programs and implemented as he did in mine.  He declared the handles in those routines as WORD.  They worked as long as I was "RUN"ing them.  When compiled, however, they no longer worked.  Thanks to John's post in this thread, I realized that the reason is that the handle parameters must be declared as LONG rather than WORD.    Is this always the case in 32 bit routines?  I note that GFA32API.ZIP documentation seems to say this but I wanted to confirm it.

Thanks,

James


#: 98072 S12/GFA  (CIS:WINAPC)
    23-Apr-97  10:07:06
Sb: #98052-Calling 32 APIs
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

 >> I just downloaded your GFA32API.ZIP.  Thank you for all the effort it
obviously entailed to produce.  I really look forward to seeing your next book which I presume this may be for.   <<

Quit good guess! I needed to test some 32-bit functions so I needed a flexible method of calling them. The first version Roland Walters program contained errors. I recently got a newer version, which seems to solve them.

>> My question is whether this is provided as an example of the only "safe" way to use 32 bit routines in a 16 bit program ... or is the purpose just to allow one to use 32bit DLLs more easily?   The reason I ask is that I am already using several 32bit DLL's in my 16 bit application (with, of course, a check to make sure the routines are only called if it is a Windows95 computer). <<

No, it is not the only safe way, it's obviously the best (g). No kiding, the method I present has a lot of advantages. Because the actual call to the Win32 API is in a DLL, the DLL can export the functions exactly as they are declared in WIN32. Parameter passing is as to any extern function (GFA will take care of passing zero-terminated string addresses, when you pass a string to a DLL). The other method always requires to add a zero-byte manually and then pass the address of the string explictely. The GFA32API interface is build in such a way, you ccan easily add calls to second party 32 bits DLL, the WOW-overhead is handled by the GFA32API.DLL. When you don't know how to do that i'll provide an example.

>>I realized that the reason is that the handle parameters must be declared as LONG rather than WORD.    Is this always the case in 32 bit routines?  I note that GFA32API.ZIP documentation seems to say this but I wanted to confirm it.<<

Confirmed! All handles are long integers. However only the window handles are manipulated, all other handles are merely longs with the hiword set to zero. See the note on window handles in the documentation.

Greetings, SH


#: 98068 S12/GFA  (CIS:WINAPC)
    23-Apr-97  09:11:10
Sb: #98053-32API RENAME?
Fm: John Findlay 100130,1771
To: James V. Schumacher 104166,2104
Replies:   0

James,

>> Is there a 32bit API I can call that is equivalent to the RENAME GFAbasic statement? <<

This is it. Perhaps you could add it to Sjoukes GFA32API.DLL; 

BOOL MoveFile(lpszExisting, lpszNew); In 'kernel32.dll' it's called MoveFileA()

LPCTSTR lpszExisting;	/* address of name of the existing file	*/
LPCTSTR lpszNew;	/* address of new name for the file	*/


The MoveFile function renames an existing file or a directory (including all its children). 

lpszExisting
	Points to a null-terminated string that names an existing file or directory. 

lpszNew
     Points to a null-terminated string that specifies the new name of a file or directory. The new name must not already exist. A new file may be on a different file system or drive. A new directory must be on the same drive. 

Returns

If the function succeeds, the return value is TRUE; otherwise it is FALSE. To get extended error information, use the GetLastError function. 

Comments

The MoveFile function will move (rename) either a file or a directory (including all its children) either in the same directory or across directories. The one caveat with this is that the MoveFile function will fail on directory moves when the destination is on a different volume. 

John


#: 98073 S12/GFA  (CIS:WINAPC)
    23-Apr-97  10:07:07
Sb: #98053-32API RENAME?
Fm: Sjouke Hamstra 100741,1036
To: James V. Schumacher 104166,2104
Replies:   0

Hi James:

Add to GFA32API as MoveFileA in the kernel32 section:

BOOL MoveFile(lpszExisting, lpszNew)

LPCTSTR lpszExisting;	/* address of name of the existing file	*/ LPCTSTR lpszNew;	/* address of new name for the file	*/


The MoveFile function renames an existing file or a directory (including all its children).

Parameter	Description

lpszExisting	Points to a null-terminated string that names an existing file or directory. lpszNew	Points to a null-terminated string that specifies the new name of a file or directory. The new name must not already exist. A new file may be on a different file system or drive. A new directory must be on the same drive.

Returns

If the function succeeds, the return value is TRUE; otherwise it is FALSE. To get extended error information, use the GetLastError function.

Comments

The MoveFile function will move (rename) either a file or a directory (including all its children) either in the same directory or across directories. The one caveat with this is that the MoveFile function will fail on directory moves when the destination is on a different volume.

Greetings, SH


#: 98086 S12/GFA  (CIS:WINAPC)
    24-Apr-97  14:09:00
Sb: Calling 32 APIs
Fm: John Findlay 100130,1771
To: All
Replies:   0

Update on WIN32's. I'm writing a DOC for these functions that will be uploaded to the library; some time! :-) I think it's all o.k. let me know if there are any mistakes.

' Add the following code to Sjoukes gfa32api.dll.
' FindFirstFile(), FindNextFile() and FindClose() was wrong previously.

'=============================
' Other added functions are;
'=============================
' MoveFile()       To rename files
' CreateFile()     Open file
' CloseHandle()    Close file
' WriteFile()      Write
' ReadFile()       Read
'=======================================================================
PROCEDURE FindFirstFile(lpszSearchFile%, lpffd%)
  $EXPORT FindFirstFile
  TRY
    RETVAL P:(lpf32%)(L:lpszSearchFile%,L:lpffd%,L:^GetProcAddress32W(hkernel32%,"FindFirstFileA"),L:%11,L:2)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE FindNextFile(hFindFile%, lpffd%)
  $EXPORT FindNextFile
  TRY
    RETVAL P:(lpf32%)(L:hFindFile%,L:lpffd%,L:^GetProcAddress32W(hkernel32%,"FindNextFileA"),L:%1,L:2)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE FindClose(hFindFile%)
  $EXPORT FindClose
  TRY
    RETVAL P:(lpf32%)(L:hFindFile%,L:^GetProcAddress32W(hkernel32%,"FindClose"),L:%0,L:1)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE MoveFile(lpszExisting%, lpszNew%)
  $EXPORT MoveFile
  TRY
    RETVAL P:(lpf32%)(L:lpszExisting%,L:lpszNew%,L:^GetProcAddress32W(hkernel32%,"MoveFileA"),L:%11,L:2)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE CreateFile(lpszName%, fdwAccess%, fdwShareMode%, lpsa%, fdwCreate%, fdwAttrsAndFlags%, hTemplateFile%)
  $EXPORT CreateFile
  TRY
    RETVAL P:(lpf32%)(L:lpszName%,L:fdwAccess%,L:fdwShareMode%,L:lpsa%,L:fdwCreate%,L:fdwAttrsAndFlags%,L:hTemplateFile%,L:^GetProcAddress32W(hkernel32%,"CreateFileA"),L:%1001000,L:7)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE CloseHandle(hObject%)
  $EXPORT CloseHandle
  TRY
    RETVAL P:(lpf32%)(L:hObject%,L:^GetProcAddress32W(hkernel32%,"CloseHandle"),L:%0,L:1)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE WriteFile(hFile%, lpBuffer%, nNumberOfBytesToWrite%, lpNumberOfBytesWritten%, lpOverlapped%)
  $EXPORT WriteFile
  TRY
    RETVAL P:(lpf32%)(L:hFile%, L:lpBuffer%,L:nNumberOfBytesToWrite%,L:lpNumberOfBytesWritten%,L:lpOverlapped%,L:^GetProcAddress32W(hkernel32%,"WriteFile"),L:%1011,L:5)
  CATCH
  RETVAL ERR
RETURN
PROCEDURE ReadFile(hFile%, lpBuffer%, nNumberOfBytesToWrite%, lpNumberOfBytesWritten%, lpOverlapped%)
  $EXPORT ReadFile
  TRY
    RETVAL P:(lpf32%)(L:hFile%, L:lpBuffer%,L:nNumberOfBytesToWrite%,L:lpNumberOfBytesWritten%,L:lpOverlapped%,L:^GetProcAddress32W(hkernel32%,"ReadFile"),L:%1011,L:5)
  CATCH
  RETVAL ERR
RETURN
'=======================================================================

'==================================================
' This code opens, writes, reads and closes a file.
'==================================================

OPENW #1,0,0,600,500,~15
@Init()

myFile$ = "c:\A LongFileNameFile.txt" + CHR$(0)
myString$ = "A file with a long file name; called 'A LongFileNameFile.txt'"
myRead$ = SPACE$(LEN(myString$))

' =========================================
' Open file for writing.
' =========================================
hFile% = ^CreateFile(V:myFile$, GENERIC_WRITE%, FILE_SHARE_WRITE%, 0, CREATE_ALWAYS%, FILE_ATTRIBUTE_NORMAL%, 0)
PRINT hFile%, "hFile%"

' =========================================
' Write to it.
' =========================================
ret| = ^WriteFile(hFile%, V:myString$, LEN(myString$), lpNumberOfBytesWritten%, 0)
PRINT ret|, "Write Return"
PRINT FileByteCount%, "FileByteCount%"

' =========================================
' Close it.
' =========================================
ret| = ^CloseHandle(hFile%)
PRINT ret|, "Close Return"

' =========================================
' Open file for reading.
' =========================================
hFile% = ^CreateFile(V:myFile$, GENERIC_READ%, FILE_SHARE_READ%, 0, OPEN_EXISTING%, FILE_ATTRIBUTE_NORMAL%, 0)
PRINT hFile%, "hFile%"

ret! = ^ReadFile(hFile%, V:myRead$, LEN(myString$), lpNumberOfBytesRead%, 0)
PRINT myRead$, "Text read from file"

ret| = ^CloseHandle(hFile%)
PRINT ret|, "Close Return"

ON MENU MESSAGE GOSUB HandleMessage

DO
  SLEEP
UNTIL MENU(1) = 4

CLOSEW #1
FREEDLL 11
END

PROCEDURE HandleMessage
  SWITCH MENU(1)
  CASE 21
  ENDSWITCH
RETURN
PROCEDURE Init()

  ' CONSTANTS

  GENERIC_READ%           = $80000000
  GENERIC_WRITE%          = $40000000
  FILE_SHARE_WRITE%       = 2
  FILE_SHARE_READ%        = 1
  CREATE_ALWAYS%          = 2
  OPEN_EXISTING%          = 3
  FILE_ATTRIBUTE_NORMAL%  = $80
  lpNumberOfBytesWritten% = V:FileByteCount%
  lpNumberOfBytesRead%    = V:FileByteCount%

  DLL #11,"E:\AA\GFA32API.DLL"

    // KERNEL32 functions
    DECL DWORD GetDriveType(l)                    // lpszRootPathName
    DECL DWORD GetLogicalDrives()
    DECL DWORD GetFullPathName(l,l,l,l)           // lpszFile, cchPath, lpszPath, ppszFilePar
    DECL DWORD GetLogicalDriveStrings(l,l)        // cchBuffer, lpszBuffer
    DECL WORD  FindFirstFile(l,l)                 // lpszSearchFile, lpffd
    DECL BOOL  FindNextFile(l,l)                  // hFindFile, lpffd
    DECL BOOL  FindClose(l)                       // hFindFile
    DECL BOOL  MoveFile(l,l)                      // lpszExisting, lpszNew
    DECL DWORD CreateFile(l,l,l,l,l,l,l)
    DECL BOOL  CloseHandle(l)
    DECL BOOL  WriteFile(l,l,l,l,l)
    DECL BOOL  ReadFile(l,l,l,l,l)

    // GDI32 functions
    DECL DWORD GetCurrentObject(l,l)              // hdc, uObjectType
    DECL BOOL  PlgBlt(l,l,l,l,l,l,l,l,l,l)        // hdcDest, lpPoint, hdcSrc, nXSrc, nYSrc, nWidth, nHeight, hbmMask, xMask,yMask

    // USER32 functions
    DECL DWORD SystemParametersInfo(l,l,l,l)      // wAction, wParam, lpvParam, fUpdateProfile

  ENDDLL

  ' Data Structure for WIN32

  TYPE FindFileDataWIN32:
  - DWORD   dwFileAttributes
  - DWORD   dwLowCreationTime
  - DWORD   dwHighCreationTime
  - DWORD   dwLowLastAccessTime
  - DWORD   dwHighLastAccessTime
  - DWORD   dwLowLastWriteTime
  - DWORD   dwHighLastWriteTime
  - DWORD   nFileSizeHigh
  - DWORD   nFileSizeLow
  - DWORD   dwReserved0
  - DWORD   dwReserved1
  - CHAR*80 cFileName$                // Max size 260 chars
  - CHAR*14 cAlternateFileName$
  ENDTYPE
  FindFileDataWIN32: finddat32.

  ' Used bitwise on finddat32.dwFileAttributes

  ATT_ARCHIVE|   = 5    // The file is an archive file.
  ATT_DIRECTORY| = 4    // The file is a directory.
  ATT_HIDDEN|    = 1    // The file is hidden.
  ATT_NORMAL|    = 7    // The file has no other attributes set.
  ATT_READONLY|  = 0    // The file is a read-only file.
  ATT_SYSTEM|    = 2    // The file is a system file.
  ATT_TEMPORARY| = 8    // The file is a temporary file.

RETURN


