Solved

Hiding Window -- WM_CREATE

Posted on 1997-05-05
14
1,047 Views
Last Modified: 2012-06-22
I'm using VB 5.0 Professional.  I am looking for a way to intercept a window before *another* application actually displays it to the user.  From what I understand, you need to set a "hook."  However, does what I want to do require the interception of the WM_CREATE?  If so, can this be done using VB 5.0?

Thanks for any help.  It's appreciated.

Regards,

Tim
0
Comment
Question by:TimH050597
  • 7
  • 3
  • 2
  • +2
14 Comments
 
LVL 3

Expert Comment

by:ChrisLewis
ID: 1425999
What are you trying to do?Try to do what you're planning in Form_Load.  It's much simpler then trying API stuff.Keep it simple!
0
 

Author Comment

by:TimH050597
ID: 1426000
Edited text of question
0
 

Author Comment

by:TimH050597
ID: 1426001
Hi,

I must've been confusing, now that I re-read my prior post, its not all that clear to me either. <g>

Anyhow, from what I understand, when applications create windows they first pass a WM_CREATE command to Windows.  I am looking for a way to intercept that command and manipulate the window myself (so the user doesn't see the window at all).

I know this is possible by setting up a hook in C++.  I haven't gotten around to getting a few books on that, so I wonder if its possible in VB 5.0?
0
 

Author Comment

by:TimH050597
ID: 1426002
Adjusted points to 200
0
 
LVL 1

Expert Comment

by:PC-Alex
ID: 1426003
Please describe what you're gonna do when caught the WM_CREATE, so that we can give you an idea how to realize it in "simple Basic".
0
 
LVL 1

Expert Comment

by:PC-Alex
ID: 1426004
Please describe what you're gonna do when caught the WM_CREATE, so that we can give you an idea how to realize it in "simple Basic".
0
 

Author Comment

by:TimH050597
ID: 1426005
Here's what I envisioned...

1.  The program catches the window in the other program before its shown to the user.
2.  My program manipulates the window by using SendMessage to close it if necessary or click a command button.

Thanks!
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:TimH050597
ID: 1426006
Adjusted points to 215
0
 

Author Comment

by:TimH050597
ID: 1426007
Adjusted points to 235
0
 

Expert Comment

by:W. Yang
ID: 1426008
I know there is a API called PeekMessage which can be used on hooking windows messages, or you can use a OCX.

But as I know all these hooking APIs and OCXs, you need a key parameter HWND, so the biggest problem is how can you know the handle of the loading application, when it is not yet displayed.

Best Regards
0
 
LVL 3

Accepted Solution

by:
dansari earned 230 total points
ID: 1426009
You can test whether the form should or should not be shown to the user in the Form_Load event.

If it should not be shown, then, from Form_Load, put in the following statement:

Unload Me

This way, the form will never be shown to the user if you don't want it to.  There should be no need to go to the Windows API for this.

0
 

Author Comment

by:TimH050597
ID: 1426010
I wish it were that simple.  I'm not referring to my program's window, another program.  It looks like a C++ DLL is the only way to do this.
0
 
LVL 3

Expert Comment

by:dansari
ID: 1426011
What you want to do is called 'subclassing' that application's window.  In order to do this, you first need to know that window's handle.  This means that the window must have been created *first* (otherwise it won't have a handle).  This window will receive a WM_CREATE message, after the window has been actually created (so it will have a handle by then).

It's not clear to me how you can hook into a window that this application creates, and hope you catch it before the window is displayed.  I suppose that may mean calling FindWindow to get that window's handle extremely often.  You'll need to use something like Spy (that comes with Visual C++) to find out that window's class name - it's one of the arguments to FindWindow.  But it might be messy, because I don't see how you can be sure of catching the handle in time.

0
 
LVL 3

Expert Comment

by:dansari
ID: 1426012
I stumbled upon this in the Win32 documentation:

PSS ID Number: Q125680
Article last modified on 07-14-1995
 
4.00
 
WINDOWS
 

----------------------------------------------------------------------
The information in this article applies to:
 
 - Microsoft Win32 Software Development Kit (SDK)
----------------------------------------------------------------------
 
SUMMARY
=======
 
While subclassing windows within the same application in Windows 95 is
unchanged from Windows version 3.1, subclassing windows belonging to other
applications is somewhat more complicated in Windows 95. This article
explains the process.
 
MORE INFORMATION
================
 
For a 16-bit application, subclassing methods are the same as they were in
Windows version 3.1. However, Windows 95 performs some behind-the-scenes
magic to make it possible for a 16-bit window to subclass a 32-bit window.
 
Usually, a subclass consists of saving one window procedure and
substituting another in its place. However, this could present a problem
when a 16-bit application tries to call a 32-bit window procedure. Windows
95 works around this potential problem by providing 32-bit windows with a
16-bit window procedure. All 32-bit windows will have the same selector for
their wndProcs that references code in KRNL386.EXE where the 16-bit
wndProcs for all 32-bit windows are stored. Eventually, each of these
16-bit wndProcs will jump to the real 32-bit window procedure.
 
Subclassing windows belonging to another process, either 16-bit or 32-bit,
from a 32-bit process or application works as it does in Windows NT. The
difficulty is that each 32-bit process has its own private address space.
Hence, a window procedure's address in one process is not valid in another.
To get a window procedure from one process into another, you need to inject
the subclass procedure code into the other process's address space. There
are a number of ways to do this.
 
Three Ways to Inject Code Into Another Process's Address Space
--------------------------------------------------------------
 
Method 1: Windows 95 and Windows NT
-----------------------------------
 
You can use the registry, hooks, or remote threads and the
WriteProcessMemory() API to inject code into another process's address
space.
 
Method 2: Windows NT Only
-------------------------
 
If you use the registry, the code that needs to be injected should reside
in a DLL. By either running REGEDIT.EXE or using the registry APIs, add the
\HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\AppInit_DLLs key to the
registry if it does not exist. Set its value to a string containing the
DLL's pathname. This key may contain more than one DLL pathname separated
by single spaces. This has the effect, once the machine is restarted, of
loading the library with DLL_PROCESS_ATTACH into every process at its
creation time. While this method is very easy, it also has several
disadvantages. For example, the computer must be restarted before it takes
effect, and the DLL will last the lifetime of the process.
 
Method 3: Windows 95 and Windows NT
-----------------------------------
 
You can also use hooks to inject code into another process's address space.
When a window hooks another thread belonging to a different process, the
system maps the DLL containing the hook procedure into the address space of
the hooked thread. Windows will map the entire DLL, not just the hook
procedure. So to subclass a window in another process, install a
WH_GETMESSAGE hook or another such hook on the thread that owns the window
to be subclassed. In the DLL that contains the hook procedure, include the
subclass window procedure. In the hook procedure, call SetWindowLong() to
enact the subclass. It is important to leave the hook in place until the
subclass is no longer needed, so the DLL remains in the target window's
address space. When the subclass is removed, the hook would be unhooked,
thus unmapping the DLL.
 
A third way to inject a DLL into another address space involves the use of
remote threads and the WriteProcessMemory() API. It is more flexible and
significantly more complicated than the previously mentioned methods, and
is described in the following reference.
 
REFERENCES
==========
 
"Load Your 32-bit DLL into Another Process's Address Space Using
INJLIB" by Jeffrey Richter, MSJ May 1994.
 
Additional reference words: 4.00
KBCategory: kbprg
KBSubcategory: UsrWndw
 
=============================================================================
 
Copyright Microsoft Corporation 1995.

**********

The SetWindowsHookEx function installs an application-defined hook procedure into a hook chain. An application installs a hook procedure to monitor the system for certain types of events. A hook procedure can monitor events associated either with a specific thread or with all threads in the system. This function supersedes the SetWindowsHook function.
HHOOK SetWindowsHookEx(
 

    int  idHook,      // type of hook to install
    HOOKPROC  lpfn,      // address of hook procedure
    HINSTANCE  hMod,      // handle of application instance
    DWORD  dwThreadId       // identity of thread to install hook for
   );      
Parameters
idHook
Specifies the type of hook procedure to be installed. This parameter can be one of the following values:
 
Value      Description

WH_CALLWNDPROC      Installs a hook procedure that monitors messages before the system sends them to the destination window procedure. For more information,  the CallWndProc hook procedure.
WH_CALLWNDPROCRET      Windows 95 only: Installs a hook procedure that monitors messages after they have been processed by the destination window procedure. For more information, see  the CallWndRetProc hook procedure.
WH_CBT      Installs a hook procedure that receives notifications useful to a computer-based training (CBT) application. For more information, see the CBTProc hook procedure.
WH_DEBUG      Installs a hook procedure useful for debugging other hook procedures. For more information, see the DebugProc hook procedure.
WH_GETMESSAGE      Installs a hook procedure that monitors messages posted to a message queue. For more information, see the GetMsgProc hook procedure.
WH_JOURNALPLAYBACK      Installs a hook procedure that posts messages previously recorded by a WH_JOURNALRECORD hook procedure. For more information, see the JournalPlaybackProc hook procedure.
WH_JOURNALRECORD      Installs a hook procedure that records input messages posted to the system message queue. This hook is useful for recording macros. For more information, see the JournalRecordProc hook procedure.
WH_KEYBOARD      Installs a hook procedure that monitors keystroke messages. For more information, see the KeyboardProc hook procedure.
WH_MOUSE      Installs a hook procedure that monitors mouse messages. For more information, see the MouseProc hook procedure.
WH_MSGFILTER      Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. For more information, see  the MessageProc hook procedure.
WH_SHELL      Installs a hook procedure that receives notifications useful to shell applications. For more information, see  the ShellProc hook procedure.
WH_SYSMSGFILTER      Installs a hook procedure that monitors messages generated as a result of an input event in a dialog box, message box, menu, or scroll bar. The hook procedure monitors these messages for all applications in the system. For more information, see  the SysMsgProc hook procedure.
lpfn
Points to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a dynamic-link library (DLL). Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
hMod
Identifies the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
dwThreadId
Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads.
Return Value
If the function succeeds, the return value is the handle of the hook procedure.
If the function fails, the return value is NULL.
Remarks
An error may occur if the hMod parameter is NULL and the dwThreadId parameter is zero or specifies the identifier of a thread created by another process.
Chaining to the next hook procedure (that is, calling the CallNextHookEx function) is optional. An application or library can call the next hook procedure either before or after any processing in its own hook procedure.
Before terminating, an application must call the UnhookWindowsHookEx function to free system resources associated with the hook.
The scope of a hook depends on the hook type. Some hooks can be set only with system scope; others can also be set for only a specific thread, as shown in the following list:
 
Hook      Scope

WH_CALLWNDPROC      Thread or system
WH_CBT      Thread or system
WH_DEBUG      Thread or system
WH_GETMESSAGE      Thread or system
WH_JOURNALPLAYBACK      System only
WH_JOURNALRECORD      System only
WH_KEYBOARD      Thread or system
WH_MOUSE      Thread or system
WH_MSGFILTER      Thread or system
WH_SHELL      Thread or system
WH_SYSMSGFILTER      System only
For a specified hook type, thread hooks are called first, then system hooks.
The system hooks are a shared resource, and installing one affects all applications. All system hook functions must be in libraries. System hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove the hook procedure.
See Also
CallNextHookEx, CallWndProc, CBTProc, DebugProc, GetMsgProc, JournalPlaybackProc, JournalRecordProc, KeyboardProc, MouseProc, MessageProc, ShellProc, SysMsgProc, UnhookWindowsHookEx

**********

The CBTProc hook procedure is an application-defined or library-defined callback function that the system calls before activating, creating, destroying, minimizing, maximizing, moving, or sizing a window; before completing a system command; before removing a mouse or keyboard event from the system message queue; before setting the keyboard focus; or before synchronizing with the system message queue. The value returned by the hook procedure determines whether Windows allows or prevents one of these operations. A computer-based training (CBT) application uses this hook procedure to receive useful notifications from the system.
LRESULT CALLBACK CBTProc(
 

    int  nCode,      // hook code
    WPARAM  wParam,      // depends on hook code
    LPARAM  lParam       // depends on hook code
   );      
Parameters
nCode
Specifies a code that the hook procedure uses to determine how to process the message. This parameter can be one of the following values:
 
Value      Meaning

HCBT_ACTIVATE      The system is about to activate a window.
HCBT_CLICKSKIPPED      The system has removed a mouse message from the system message queue. Upon receiving this hook code, a CBT application must install a WH_JOURNALPLAYBACK hook procedure in response to the mouse message.
HCBT_CREATEWND      A window is about to be created. The system calls the hook procedure before sending the WM_CREATE or WM_NCCREATE message to the window. If the hook procedure returns a nonzero value, the system destroys the window; the CreateWindow function returns NULL, but the WM_DESTROY message is not sent to the window. If the hook procedure returns zero, the window is created normally.
      At the time of the HCBT_CREATEWND notification, the window has been created, but its final size and position may not have been determined and its parent window may not have been established. It is possible to send messages to the newly created window, although it has not yet received WM_NCCREATE or WM_CREATE messages. It is also possible to change the position in the Z order of the newly created window by modifying the hwndInsertAfter member of the CBT_CREATEWND structure.
HCBT_DESTROYWND      A window is about to be destroyed.
HCBT_KEYSKIPPED      The system has removed a keyboard message from the system message queue. Upon receiving this hook code, a CBT application must install a WH_JOURNALPLAYBACK hook procedure in response to the keyboard message.
HCBT_MINMAX      A window is about to be minimized or maximized.
HCBT_MOVESIZE      A window is about to be moved or sized.
HCBT_QS      The system has retrieved a WM_QUEUESYNC message from the system message queue.
HCBT_SETFOCUS      A window is about to receive the keyboard focus.
HCBT_SYSCOMMAND      A system command is about to be carried out. This allows a CBT application to prevent task switching by means of hot keys.
If nCode is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
wParam
Depends on the nCode parameter. For details, see the following Remarks section.
lParam
Depends on the nCode parameter. For details, see the following Remarks section.
Return Value
For operations corresponding to the following CBT hook codes, the return value must be 0 to allow the operation, or 1 to prevent it:
HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND
For operations corresponding to the following CBT hook codes, the return value is ignored:
HCBT_CLICKSKIPPED
HCBT_KEYSKIPPED
HCBT_QS
Remarks
The hook procedure should not install a WH_JOURNALPLAYBACK hook procedure except in the situations described in the preceding list of hook codes.
This hook procedure must be in a dynamic-link library (DLL). An application installs the hook procedure by specifying the WH_CBT hook type and the address of the hook procedure in a call to the SetWindowsHookEx function.
The following table describes the wParam and lParam parameters for each HCBT_ hook code:
 
Value      wParam      lParam

HCBT_ACTIVATE      Specifies the handle to the window about to be activated.      Specifies a long pointer to a CBTACTIVATESTRUCT structure containing the handle to the active window and specifies whether the activation is changing because of a mouse click.  
HCBT_CLICKSKIPPED      Identifies the mouse message removed from the system message queue.      Specifies a long pointer to a MOUSEHOOKSTRUCT structure containing the hit-test code and the handle to the window for which the mouse message is intended. The HCBT_CLICKSKIPPED value is sent to a CBTProc hook procedure only if a WH_MOUSE hook is installed. For a list of hit-test codes, see WM_NCHITTEST .  
HCBT_CREATEWND      Specifies the handle to the new window.      Specifies a long pointer to a CBT_CREATEWND structure containing initialization parameters for the window. The parameters include the coordinates and dimensions of the window. By changing these parameters, a CBTProc hook procedure can set the initial size and position of the window.  
HCBT_DESTROYWND      Specifies the handle to the window about to be destroyed.      Is undefined and must be set to zero.
HCBT_KEYSKIPPED      Identifies the virtual-key code.      Specifies the repeat count, scan code, key-transition code, previous key state, and context code. The HCBT_KEYSKIPPED value is sent to a CBTProc hook procedure only if a WH_KEYBOARD hook is installed. For more information, see the WM_KEYUP or WM_KEYDOWN message.
HCBT_MINMAX      Specifies the handle to the window being minimized or maximized.      Specifies, in the low-order word, a show-window value (SW_) specifying the operation. For a list of show-window values, see the ShowWindow. The high-order word is undefined.
HCBT_MOVESIZE      Specifies the handle to the window to be moved or sized.      Specifies a long pointer to a RECT structure containing the coordinates of the window. By changing the values in the structure, a CBTProc hook procedure can set the final coordinates of the window.  
HCBT_QS      Is undefined and must be zero.      Is undefined and must be zero.
HCBT_SETFOCUS      Specifies the handle to the window gaining the keyboard focus.      Specifies the handle to the window losing the keyboard focus.
HCBT_SYSCOMMAND      Specifies a system-command value (SC_) specifying the system command. For more information about system-command values, see WM_SYSCOMMAND.       Contains the same data as the lParam value of a WM_SYSCOMMAND message: If a system menu command is chosen with the mouse, the low-order word contains the x-coordinate of the cursor, in screen coordinates, and the high-order word contains the y-coordinate; otherwise, the parameter is not used.
CBTProc is a placeholder for the application-defined or library-defined function name.
See Also
CallNextHookEx, CreateWindow, SetWindowsHookEx, WM_SYSCOMMAND

**********

You'll need to know the thread of the program that creates the window, and it may be possible to intercept WM_CREATE for the particular window you're interested in by using a CBTProc hook.  This is getting into advanced Windows stuff, so good luck!

I haven't done this before, so I can't help you much further.  If you have any questions, you can try asking me.

daniel@cherniak.on.ca

0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
When trying to find the cause of a problem in VBA or VB6 it's often valuable to know what procedures were executed prior to the error. You can use the Call Stack for that but it is often inadequate because it may show procedures you aren't intereste…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now