Skip navigation

Category Archives: windows

Windows shell scripting

fantastic

The %stuff%

There are several items that you can use that looks like %this%.

  • %PATH%
  • %APPDATA%
  • %DATE%
  • %TIME%

basically, these %this% is how you access any of the environment variables defined on your system. Right click My Computer > Properties > Advanced > Environment Variables

Those are all the environment variables on your system.

At CMD:

C:\> echo %APPDATA%

HKLM local machine variables (bottom half) supercede current user variables (top half). Well, if you have a PATH variable defined as both HKLM and HKCU then if you echo %PATH% it gives you the HKLM machine variable; CONTENATE HKCU variable

Substring: %VAR:offset,len%

e.g.

echo %DATE:~1,2%    REM If its Dec, gives ec.  Starting at position 1, get 2 chars
echo %DATE:~1%      REM Goes from position 1 to end of string.  ec 27 08

Above example not that useful, but at least its clear how to work it

Getting random user input.

Try putting this into test.bat, then running it:

set /P MyAnswer=Tell me something: 

echo You said: "%MyAnswer%"

pause

Thanks to this guy again for that neat tip!

Well, I’m getting increasingly frustrated with my inability to shell script.

How many times have I went through about 200 folders, manually unzipping the contents, when I really should be able to somehow write a batch script that does that?

Or copy a single file into every subfolder of a directory. That’s a common task

or desubversion-ize or decvs-ize a copy of a repository dir (sometimes I back up by ctrl+c ctrl+v on local machine (just for archiving purposes!) and need to delete *.svn. Can’t you just do del *.svn /s though? I don’t know. haven’t tried it.)

Or truncate a directory name. I have this really shitty tool I have to use at work which gives me hundreds of items separated into folders, but they have names like:

Something-Last, Firstname Mr () – 4288282858258

So the last pair of brackets (function call or whatever its trying to be) and the 4288282858258 registration number means nothing to me. Yet every folder has these things. I could also do without the title (Mr.). So basically I’d like to truncate the last _4_ “words” (separated by spaces), or I’d like to truncate everything from the last capital M to the end (Mr, Ms, Miss and Capt are the titles they give. Capt is RARE, so we can ignore it as a use case).

msdn command line reference

An A-Z Index of the Windows XP command line (AWESOME)

windows nt shell scripting

windows script host

windows powersHELL!!

But that still doesn’t teach me how to write a script that, say, like this page seems to. let me look at that now.

its easy!

in your WndProc, add a trapping for

#define WM_QUERYENDSESSION  0x11
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
  switch( message )
  {
    case WM_QUERYENDSESSION:
      return 0; // cancel the shutdown
  }
}

That’s really it!

The trackbar is notorious for giving people trouble when trying to get started with it.

It doesn’t help that the docs or the really poor example page don’t say ANYTHING about what I’m about these small but annoying issues.

MY TRACKBAR WON’T SHOW UP!!

Try looking up the error code. If its a 1407, that’s “Cannot find window class.” That happens because you didn’t call:

InitCommonControls();

error C2065: ‘TRACKBAR_CLASS’ : undeclared identifier!

You have to

#include <commctrl.h>

error LNK2019: unresolved external symbol __imp__InitCommonControls@0 referenced in function _WinMain@16

You have to

#pragma comment( lib, "comctl32.lib" )

Here’s a real quick example of how to get the trackbar working in a basic win32 app (no mfc or .net stuff), fast.

//////////////////////////////////////////
//                                      //
// Trackbars                            //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 13/08            //
// Last modified:  Feb 13/08            //
//                                      //
//////////////////////////////////////////

#include <windows.h>
#include <commctrl.h>       // must have

#pragma comment( lib, "comctl32.lib" )  // must have

////////////////////////
// TRACKBARS!

// We want to add trackbars to our
// windows application.

#define IDCHC_TRACKBAR 4

/////////////////////
// GLOBALS
HWND g_hwnd;
HWND g_trackbarhwnd;
//
/////////////////////

// Function prototypes.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );


////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
    #pragma region part 1 - create a window
    // A.  Create the WNDCLASS
    WNDCLASS wc;
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hbrBackground = GetSysColorBrush( COLOR_APPWORKSPACE );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wc.hInstance = hInstance;
    wc.lpfnWndProc = WndProc;
    wc.lpszClassName = TEXT("Philip");
    wc.lpszMenuName = 0; 
    wc.style = CS_HREDRAW | CS_VREDRAW;

    // B.  Register the WNDCLASS with Windows, THEN
    //     create the window.
    RegisterClass( &wc );
    g_hwnd = CreateWindow(
        TEXT("Philip"),
        TEXT("windows app"),
        WS_OVERLAPPEDWINDOW,
        10, 10,
        400, 400,
        NULL, NULL,
        hInstance, NULL );      

    ShowWindow(g_hwnd, iCmdShow );
	UpdateWindow(g_hwnd);
    #pragma endregion

    #pragma region add the trackbar
    InitCommonControls();
    g_trackbarhwnd = CreateWindow(
        TRACKBAR_CLASS, // USE PREDEFINED CLASS
                        // MUST #include  TO USE

        TEXT("da trackbar son"),    // doesn't matter what
                                    // you call it -

        WS_CHILD | WS_VISIBLE |
        // next are the Trackbar styles
        TBS_AUTOTICKS |        // trackbar has tick marks
        TBS_HORZ,              // horizontal orientation
        100, 100,
        200, 30,
        g_hwnd,//parent
        (HMENU)IDCHC_TRACKBAR,  // identifier
        hInstance,  //(HINSTANCE)GetWindowLong( g_hwnd, GWL_HINSTANCE ),
        NULL );

    if( g_trackbarhwnd == NULL )
    {
        TCHAR errbuf[300];
        wsprintf( errbuf, TEXT("error code #%d"), GetLastError() );
        FatalAppExit( 0, errbuf );
    }
    
    /////////////////
    // NOW, as SOON AS the track bar is created,
    // we pelt it with some messages to give it
    // additional information about how we want
    // it to be.  If your computer was INCREDIBLY (20MHz?)
    // slow, you'd see these changes taking place,
    // because the trackbar has already been created
    // and made visible on the main window itself
    // in the line above.
    SendMessage(g_trackbarhwnd,     // hwnd - handle to trackbar
                TBM_SETRANGE,       // message - a message to set the range
                true,               // wparam - redraw it?  yes.
                MAKELONG(0/*MIN RANGE*/, 10/*MAX RANGE*/));  // lparam
    
    // The only tricky part is lparam.
    
    // We have to use a tricky macro called MAKELONG.

    ///////////
    // SUPERFICIALLY:
    // You know how when you're processing a
    // WM_LBUTTONDOWN mouse message, the x AND
    // y position of the mouse are BOTH packed
    // into the single variable lparam?
/*
case WM_LBUTTONDOWN:
    int x = LOWORD( lparam );
    int y = HIWORD( lparam );
    break;
*/
    // WELL, MAKELONG( a, b ) works to PACK
    // a and b into a SINGLE variable of type
    // long.

    // It uses bitshifting to do so.
    // Look at its #define if interested.

    // You can send plenty of other messages
    // to your trackbar to customize its look and
    // behavior!

    SendMessage(g_trackbarhwnd, TBM_SETPAGESIZE, true, 1); 
    SendMessage(g_trackbarhwnd, TBM_SETTICFREQ, true, 0); 
    SendMessage(g_trackbarhwnd, TBM_SETPOS, true, 0); 
    SendMessage(g_trackbarhwnd, TBM_SETSEL, true, MAKELONG( 1, 5 ) );
                

    #pragma endregion

    #pragma region part 2 - enter message loop
    MSG msg;

    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    #pragma endregion

    return msg.wParam;
}

LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 
{
    switch( message )
    {
    case WM_CREATE:
        Beep( 50, 10 );
        return 0;
        break;

    case WM_PAINT:
        {
            HDC hdc;
            PAINTSTRUCT ps;
            hdc = BeginPaint( hwnd, &ps );
                // Nothing to draw.
            EndPaint( hwnd, &ps );
        }
        return 0;
        break;

    case WM_KEYDOWN:
        switch( wparam )
        {
        case VK_ESCAPE:
            PostQuitMessage( 0 );
            break;
        default:
            break;
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage( 0 ) ;
        return 0;
        break;
    }
 
    return DefWindowProc( hwnd, message, wparam, lparam );
}




/* 
     ____   __   __      __   __  ___
    / _  \ /  / /  /    /  /  \ \/  /
   / _/ / /  / /  /    /  /    \   /
  / _/ \ /  / /  /__  /  /__   /  /
 /_____//__/ /______//______/ /__/

*/

Visual Studio 2005 project files for Trackbar on Win32 hosted by esnips (thanks esnips!)

There’s a good msdn article on window translucency using layered windows here.

//////////////////////////////////////////
//                                      //
// COOL TRANSLUCENT WINDOWS!            //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 13/08            //
// Last modified:  Feb 13/08            //
//                                      //
//////////////////////////////////////////


#define _WIN32_WINNT    0x0500  // ya hafta have this
// to use WS_EX_LAYERED . . it tells the compiler
// you're compiling for a platform Windows 2000
// or better 

//////////////////////////
// Using CreateWindowEx() -- why???
//
// Now you may have noticed that there's
// TWO functions that you can use
// to create a window:
//     CreateWindow();
// and
//     CreateWindowEx();

// Why use CreateWindowEx()?  Well, 
// one reason is you can make
// COOL TRANSLUCENT WINDOWS!!

// There's a ton of other features that
// you can use for Windows that have
// "EXTENDED WINDOW STYLES" -- see 
// the CreateWindowEx() docs on msdn

#include <windows.h>



/////////////////////
// GLOBALS
HWND g_hwnd;        // just a global for hwnd
//
/////////////////////

// Function prototypes.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );


////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
    #pragma region part 1 - use a WNDCLASSEX structure to create a window!!
    // A.  Create the WNDCLASSEX structure.
    //
    // The EX is for "EXTENDED".
    //
    // The WNDCLASSEX structure is very similar to
    // the plain old WNDCLASS structure, EXCEPT
    // that it has quite a few "EXTENDED STYLES!"
    //
    // Let's create a structure and explore.
    WNDCLASSEX wcx;

    wcx.cbClsExtra = 0; 
    wcx.cbSize = sizeof( WNDCLASSEX );  // 1.  NEW!  must know its own size.
    wcx.cbWndExtra = 0; 
    wcx.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wcx.hCursor = LoadCursor( NULL, IDC_ARROW );         
    wcx.hIcon = LoadIcon( NULL, IDI_APPLICATION );     
    wcx.hIconSm = NULL;                 // 2.  NEW!!  Can specify small icon.
    wcx.hInstance = hInstance;         
    wcx.lpfnWndProc = WndProc;         
    wcx.lpszClassName = TEXT("Philip");
    wcx.lpszMenuName = 0; 
    wcx.style = CS_HREDRAW | CS_VREDRAW;

    //////////////////////////////
    // AWW.  Disappointed?  There were only
    // TWO new fields in the WNDCLASSEX structure,
    // and they weren't very exciting
        // (cbSize and hIconSm.)

    //////////////
    // BUT WAIT!!  The cool stuff is yet to come.

    // First, we get to use the RegisterClassEx() function
    // (no more plain old RegisterClass()!!!)
    // to register our WNDCLASSEX struct!! WEEHEE!
    // Actually that is not that cool.

    // B.  Register the WNDCLASSEX with Windows, THEN
    //     create the window.
    RegisterClassEx( &wcx );    // use RegisterClassEx() func!

    //////////////////
    // OK NOW IS THE COOL PART!!  We get
    // to use CreateWindowEx() to actually
    // create our window.  CreateWindowEx()
    // has ONE new params is COOL:
    g_hwnd = CreateWindowEx(
        WS_EX_LAYERED,  // NEW PARAMETER!!
            // EXTENDED STYLES! This "layered
            // style will allow us to make our window
            // TRANSLUCENT (partly see thru!)
        // "Note that WS_EX_LAYERED cannot be used for child windows."

        TEXT("Philip"), // rest are same old.
        TEXT("OOOOOOOOOOOOOOOOH!!! GHOSTLY WINDOW!!"),
        WS_OVERLAPPEDWINDOW,
        10, 10,
        400, 400,
        NULL, NULL,
        hInstance, NULL );

    /////////////
    // SetLayeredWindowAttribute:
    // MUST CALL THIS if using WS_EX_LAYERED.
    // http://msdn2.microsoft.com/en-us/library/ms633540(VS.85).aspx
    SetLayeredWindowAttributes( g_hwnd,     // handle to window to modify
                                0,          // color key (not used when using LWA_ALPHA)
                                85,         // "amount of solidness" = 0=transparent, 255=completely solid
                                LWA_ALPHA );// use my alpha value (prev arg)
                                            // to tell how see 'solid' window is.

    // Try this too, for a weird effect:
    /*
    SetWindowText( g_hwnd, TEXT("All white parts are see thru AND click thru!") );
    SetLayeredWindowAttributes( g_hwnd,         // handle to window to modify
                                RGB(255,255,255),  // colorkey
                                255,            // 0=transparent, 255=completely solid
                                LWA_COLORKEY);  // use COLORKEY specified
                                                // in 2nd arg to be
                                                // TRANSPARENT (leaves holes
                                                // in window
    */

    ShowWindow(g_hwnd, iCmdShow );
    UpdateWindow(g_hwnd);
    #pragma endregion

    #pragma region part 2 - enter message loop
    MSG msg;

    while( GetMessage(&msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    #pragma endregion

    return msg.wParam;
}

LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 
{
    switch( message )
    {
    case WM_CREATE:
        Beep( 50, 10 );
        return 0;
        break;

    case WM_CHAR:
        switch( wparam )
        {
        case 'G':   // make ghostly
        case 'g':
            // maintain old style, turn on WS_EX_LAYERED bits on.
            SetWindowLongPtr(   hwnd, 
                GWL_EXSTYLE, 
                GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);

            SetLayeredWindowAttributes( hwnd,
                0,
                85,  /* "amount of solidness" 0=transparent, 255=solid*/
                LWA_ALPHA);
            // Everytime you make a window ghostly,
            // you MUST call SetLayeredWindowAttributes(),
            // otherwise it won't work properly.
            break;

        case 'S':   // make solid
        case 's':
            // Remove WS_EX_LAYERED from this window's style
            SetWindowLongPtr(   hwnd, 
                GWL_EXSTYLE,    // set the EX_STYLE of this window
                GetWindowLong(hwnd, GWL_EXSTYLE) &  // GET old style first
                ~WS_EX_LAYERED);  // turn WS_EX_LAYERED bits off

            // Note:  Use SetWindowLongPtr (NOT SetWindowLong()!)
            // to write code that'll work
            // on both 32-bit and 64-bit windows!
            // http://msdn2.microsoft.com/en-us/library/ms644898(VS.85).aspx
        }
        return 0;
        break;


    case WM_PAINT:
        {
            HDC hdc;
            PAINTSTRUCT ps;
            hdc = BeginPaint( hwnd, &ps );
            
            EndPaint( hwnd, &ps );
        }
        return 0;
        break;

    case WM_KEYDOWN:
        switch( wparam )
        {
        case VK_ESCAPE:
            PostQuitMessage( 0 );
            break;
        default:
            break;
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage( 0 ) ;
        return 0;
        break;
    }
 
    return DefWindowProc( hwnd, message, wparam, lparam );
}

// Toggle the "ghostliness" sample code from:
// http://msdn2.microsoft.com/en-us/library/ms632598(VS.85).aspx


/* 
     ____   __   __      __   __  ___
    / _  \ /  / /  /    /  /  \ \/  /
   / _/ / /  / /  /    /  /    \   /
  / _/ \ /  / /  /__  /  /__   /  /
 /_____//__/ /______//______/ /__/

*/

Source code available on esnips in Visual Studio 2005 project files package

We know.


edit: that’s what you get for leaving an incomplete posting!

The previously cited msdn article is GONE. I didn’t know microsoft did that, but its REALLY annoying.

概要 Overview 
詳細 Details 
サンプルコード Sample code 
関連情報 Related Information 
すべて展開する | すべて折りたたむ Expand All | Collapse All 
概要 Overview Microsoft Windows NT 4.0 と Microsoft Windows 98 は、マウスがウィンドウを離れたことをウィンドウに通知する TrackMouseEvent API を提供しています。 Microsoft Windows NT 4.0 and Microsoft Windows 98, to notify the window that the mouse off the window TrackMouseEvent API provides. Windows 95 では、このような通知方法を提供していません。 Windows 95 does not provide this notification method. アプリケーションは、マウスがウィンドウ内に入った時にタイマーを起動し、そのタイマーを使ってマウスの位置を監視して、ウィンドウ範囲内にあるかを判断することによって、マウスがウィンドウ外に出たことを検出できます。 Application, start the timer when the mouse enters the window, to monitor the position of the mouse using a timer, or by a judge within the window, out the window that the mouse can be detected. 
 先頭へ戻る Back to the top 
詳細 Details 以下のサンプルコードは、TrackMouseEvent のインタフェースを使うように、Windows NT3.51 と Windows 95 で、マウスが離れたことを検出する方法を示した例です。 The following sample code, TrackMouseEvent to use interface, Windows NT3.51 with Windows 95, is an example of how to detect that the mouse away. WM_MOUSEHOVER の機能の実現は読者にお任せいたします。 We realize the function of WM_MOUSEHOVER leave it to your readers. 
 先頭へ戻る Back to the top 
サンプルコード Sample code 
    #if(_WIN32_WINNT < 0x0400) # if (_WIN32_WINNT cbSize  cbSize hwndTrack)) { if (! IsWindow (ptme-> hwndTrack)) ( 
          OutputDebugString( OutputDebugString ( 
             TEXT("TrackMouseEvent: invalid hwndTrack\n")); TEXT ( "TrackMouseEvent: invalid hwndTrack \ n")); 
          return FALSE; return FALSE; 
       } ) 

       if (!(ptme->dwFlags & TME_LEAVE)) { if (! (ptme-> dwFlags & TME_LEAVE)) ( 
          OutputDebugString(TEXT("TrackMouseEvent: invalid dwFlags\n")); OutputDebugString (TEXT ( "TrackMouseEvent: invalid dwFlags \ n")); 
          return FALSE; return FALSE; 
       } ) 

       return SetTimer(ptme->hwndTrack, ptme->dwFlags, return SetTimer (ptme-> hwndTrack, ptme-> dwFlags, 
                       100,(TIMERPROC)TrackMouseTimerProc); 100, (TIMERPROC) TrackMouseTimerProc); 
    } ) 
    #endif # endif 

    LRESULT CALLBACK LRESULT CALLBACK 
    MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
    { ( 
       TRACKMOUSEEVENT tme; TRACKMOUSEEVENT tme; 
       static BOOL fInWindow; static BOOL fInWindow; 
       static BOOL fInMenu; static BOOL fInMenu; 
       switch (uMsg) { switch (uMsg) ( 
          case WM_CREATE: case WM_CREATE: 
             fInWindow = FALSE; fInWindow = FALSE; 
             fInMenu = FALSE; fInMenu = FALSE; 
             return 0; return 0; 

          case WM_MOUSEMOVE: case WM_MOUSEMOVE: 
             if (!fInWindow) { if (! fInWindow) ( 
                fInWindow = TRUE; fInWindow = TRUE; 
                tme.cbSize = sizeof(TRACKMOUSEEVENT); tme.cbSize = sizeof (TRACKMOUSEEVENT); 
                tme.dwFlags = TME_LEAVE; tme.dwFlags = TME_LEAVE; 
                tme.hwndTrack = hWnd; tme.hwndTrack = hWnd; 
                if (!TrackMouseEvent(&tme)) { if (! TrackMouseEvent (& tme)) ( 
                   MessageBox(hWnd, MessageBox (hWnd, 
                              TEXT("TrackMouseEvent Failed"), TEXT ( "TrackMouseEvent Failed"), 
                              TEXT("Mouse Leave"),MB_OK); TEXT ( "Mouse Leave"), MB_OK); 
                } ) 
             } ) 
          break; 

          case WM_MOUSELEAVE: case WM_MOUSELEAVE: 
             fInWindow = FALSE; fInWindow = FALSE; 
             if (!fInMenu) if (! fInMenu) 
                MessageBox(hWnd,TEXT("Elvis has left the building"), MessageBox (hWnd, TEXT ( "Elvis has left the building"), 
                           TEXT("Mouse Leave"),MB_OK); TEXT ( "Mouse Leave"), MB_OK); 
             break; 
          case WM_ENTERMENULOOP: case WM_ENTERMENULOOP: 
             fInMenu = TRUE; fInMenu = TRUE; 
             break; 

          case WM_EXITMENULOOP: case WM_EXITMENULOOP: 
             fInMenu = FALSE; fInMenu = FALSE; 
             break; 

          default: 
             return DefWindowProc(hWnd,uMsg,wParam,lParam); return DefWindowProc (hWnd, uMsg, wParam, lParam); 
       } ) 
       return FALSE; return FALSE; 
    } ) 

   (c) Microsoft Corporation 1997, All Rights Reserved. (c) Microsoft Corporation 1997, All Rights Reserved. 
   Contributions by Rob Caplan, Microsoft Corporation Contributions by Rob Caplan, Microsoft Corporation 


 先頭へ戻る Back to the top 
関連情報 Related Information この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 183107 (http://support.microsoft.com/kb/183107/EN-US/ ) (最終更新日 1999-02-22) をもとに作成したものです。 Microsoft Corporation on this article are available from the Knowledge Base Article ID 183107 (http://support.microsoft.com/kb/183107/EN-US/) (Last Updated 1999-02-22) based on what you think. 


 先頭へ戻る Back to the top 

--------------------------------------------------------------------------------

この資料は以下の製品について記述したものです。 This article was first listed in the following table. 
Microsoft Platform SDK January 2000 Edition Microsoft Platform SDK January 2000 Edition 
Microsoft Windows NT Server 3.5 Microsoft Windows NT Server 3.5 
Microsoft Windows NT Server 3.51 Microsoft Windows NT Server 3.51 
Microsoft Windows NT Server 4.0 Standard Edition Microsoft Windows NT Server 4.0 Standard Edition 
Microsoft Windows NT Workstation 3.5 Microsoft Windows NT Workstation 3.5 
Microsoft Windows NT Workstation 3.51 Microsoft Windows NT Workstation 3.51 
Microsoft Windows NT Workstation 4.0 Developer Edition Microsoft Windows NT Workstation 4.0 Developer Edition 
Microsoft Windows 95 Microsoft Windows 95 
Microsoft Windows 98 Standard Edition Microsoft Windows 98 Standard Edition 
Microsoft Windows 2000 Advanced Server Microsoft Windows 2000 Advanced Server 
Microsoft Windows 2000 Server Microsoft Windows 2000 Server 
Microsoft Windows 2000 Professional Microsoft Windows 2000 Professional 
 先頭へ戻る Back to the top 
キーワード: Keywords:  kbinfo trackmouseevent KB183107 kbinfo trackmouseevent KB183107  

 先頭へ戻る Back to the top 
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。" "Microsoft Knowledge Base that contains the information is provided by the base warranty of any kind. Microsoft Corporation and its affiliates, including times for this problem, explicitly in Brazil, and more. In addition, Microsoft Corporation and their affiliates, to use of the information contained in this document, the accuracy, truth, and to Reproduce section also. Microsoft Corporation, or advice of any information provided orally or in writing the power of these are not the top, click the above disclaimer and do not . Microsoft Corporation, the reliability of these are direct, indirect, accidental, consequential damage, lost profits, punitive damages, including damages for loss of or all the circumstances not be responsible for any. (Microsoft Corporation, then you will have the possibility of such damages the reliability of the computer.) accidental or consequential damage In the current exemption of liability for damages, you may not click OK. Microsoft is a registered trademark shown in the name of the product represented by the top Keywords: Other We may have to skip the show, please OK. " 

The only article like it I could find is this one, translated from japanese

WM_MOUSELEAVE notification on msdn now.

OpenGL Windows

How do you get OpenGL to run in a Windows app WITHOUT using GLUT?

Here’s an example, commented in detail, showing how. Emphasis on “easy to understand.”

//////////////////////////////////////////
//                                      //
// OpenGL in a PROPER Windows APP       //
// ( NO GLUT !! )                       //
//                                      //
// You found this at bobobobo's weblog, //
// https://bobobobo.wordpress.com        //
//                                      //
// Creation date:  Feb 9/08             //
// Last modified:  Feb 10/08            //
//                                      //
//////////////////////////////////////////

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <gl/gl.h>
#include <gl/glu.h>

#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")


////////////////////////
// OK, here's the deal.
//
// OpenGL is typically so hard to
// get started on Windows (what, with the
// HDC and the HGLRC and the PIXELFORMATDESCRIPTOR)
// most get turned off very quickly
// and stick with GLUT for a very long time,
// because GLUT hides away A LOT of the
// complexities of getting a window up
// and drawing into it.

// If you're still reading, you're
// probably tired of doing things the
// GLUT way, and you want to cross over
// to doing things in OpenGL using a pure
// Windows application.

// Good choice my friend!  If you want
// full control over your app, you'll 
// want to do things in pure Win32.

// Once you get used to programming in Win32,
// its not ALL THAT BAD, I promise (evil grin).

// This demo shows you how to get a basic
// window up that OpenGL can draw into,
// and explains each step in detail.

// I give some additional references at the
// bottom of the page.

//////////////////////////
// OVERVIEW:
//
// The OUTPUT of OpenGL is a two dimensional
// PICTURE of a 3D scene.

// That's right.  I said 2D.

// People often say that the process OpenGL
// goes through to render a 3D scene is just like
// a CAMERA TAKING A PHOTOGRAPH OF A REAL WORLD SCENE.
//
// So, you know obviously that a PHOTOGRAPH
// is PURELY 2D after its been developed,
// and it DEPICTS the 3D scene that it
// "took a picture" of accurately.

// That's exactly what OpenGL does.  OpenGL's JOB
// is to take all your instructions, all your
// glColor3f()'s and your glVertex3f()'s, and
// to ultimately end up DRAWING A 2D PICTURE
// from those instructions that can be displayed
// on a computer screen.

// In THIS program, our MAIN GOAL is to
// CONNECT UP the OUTPUT of OpenGL (that 2D
// image OpenGL produces)
// with YOUR APPLICATION'S WINDOW.

// Does this look familiar?

/*
     HDC hdc = GetDC( hwnd );
*/

// You should already know that the way
// you as a Windows programmer draw to
// your application's window is using
// your window's HDC.

// If this doesn't sound familiar,
// then I strongly recommend you go read up
// on Win GDI before continuing!

////////////////////////////////!
//
// So if our way to draw to our application window
// is the HDC, and OpenGL produces some 2D image
// HOW IN THE WORLD DO YOU CONNECT UP the OUTPUT
// of the OpenGL program (that 2D picture)
// WITH the HDC of a WINDOW?
//
// That's the main subject we're tackling here
// in this tutorial.
//
// And its EASY.
//
// WE'RE lucky.  Microsoft created a bunch
// of functions (all beginning with "wgl"),
// that make this job of "connecting up" the output
// of OpenGL with the HDC of our window quite easy!

/////////////////////////
// BIG PICTURE:
//
// Here's the big picture of what
// we're going to be doing here:

/*

|---------|  draws to   |-------|  copied out   |---------|  shows in  |-----------|
|         | ==========> |       | ============> |         | =========> |           |
|---------|             |-------|               |---------|            |-----------|
  OPENGL                  HGLRC                     HDC                 application
 FUNCTION                                                                 window
  CALLS                                                                     

*/

//////////////////////
// In code:  this is the steps
// we'll follow.
//
// 1.  CREATE WINDOW AS USUAL.
//
// 2.  GET DC OF WINDOW.
//     Get the HDC of our window using a line like:
//          hdc = GetDC( hwnd );
//
// 3.  SET PIXEL FORMAT OF HDC.
//     You do 3 things here:
//          Create a PFD ('pixel format descriptor')
//          ChoosePixelFormat()
//          SetPixelFormat()
//
// 4.  CREATE RENDERING CONTEXT (HGLRC).
//          wglCreateContext()
//     Create the surface to which OpenGL
//     shall draw.  It is created such that
//     it shall be completely compatible
//     with the DC of our window, (it will
//     use the same pixel format!)
//
// 5.  CONNECT THE RENDER CONTEXT (HGLRC)
//     WITH THE DEVICE CONTEXT (HDC) OF WINDOW.
//          wglMakeCurrent()
//
// 6.  DRAW USING OPENGL.
//          glVertex3d(); glColor3d(); // ETC!
//     You call OpenGL functions to perform
//     your drawing!  OpenGL will spit out
//     its result picture to the HGLRC, which is
//     connected to the backbuffer of your HDC.
//
// 7.  SWAP BUFFERS.
//          SwapBuffers( hdc );	
//     Assuming you've picked a DOUBLE BUFFERED
//     pixel format all the way back in step 2, 
//     you'll need to SWAP the buffers so that
//     the image you've created using OpenGL on
//     the backbuffer of your hdc is shown
//     in your application window.

// And that's all!

// Ready for the code??? Let's go!

/////////////////////
// GLOBALS
//
/// Define a structure to hold all
/// of the global variables of this app.
struct Globals
{
    HINSTANCE hInstance;    // window app instance

    HWND hwnd;      // handle for the window

    HDC   hdc;      // handle to device context

    HGLRC hglrc;    // handle to OpenGL rendering context
    
    int width, height;      // the desired width and
    // height of the CLIENT AREA
    // (DRAWABLE REGION in Window)
};


///////////////////////////
// GLOBALS
// declare one struct Globals called g;
Globals g;
//
///////////////////////////


// Function prototypes.
LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam );
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow );
void draw();            // drawing function containing OpenGL function calls

////////////////////////////
// In a C++ Windows app, the starting point is WinMain().
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow )
{
    //////////////////
    // First we'll start by saving a copy of
    // the hInstance parameter inside our
    // "glob" of globals "g":
    g.hInstance = hInstance;

    #pragma region part 1 - create a window
    // The next few lines you should already
    // be used to:  create a WNDCLASS
    // that describes the properties of
    // the window we're going to soon create.
    // A.  Create the WNDCLASS
    WNDCLASS wc;
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
    wc.hCursor = LoadCursor( NULL, IDC_ARROW );         
    wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );     
    wc.hInstance = hInstance;         
    wc.lpfnWndProc = WndProc;         
    wc.lpszClassName = TEXT("Philip");
    wc.lpszMenuName = 0; 
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;

    // Register that class with the Windows O/S..
	RegisterClass(&wc);
    
    /////////////////
    // Ok, AT THIS POINT, we'd normally
    // just go ahead and call CreateWindow().
    // And we WILL call CreateWindow(), but
    // there is something I must explain to
    // you first.  That thing is the RECT structure.

    /////////////////
    // RECT:
    //
    // A RECT is just a C struct meant to represent
    // a rectangle.
    // 
    // The RECT structure WILL DESCRIBE EXACTLY WHERE
    // AND HOW WE WANT OUR WINDOW TO APPEAR WHEN WE
    // CREATE IT.
    //
    //         TOP
    //       --------
    //       |      |
    // LEFT  |      | RIGHT
    //       --------
    //        BOTTOM
    //
    // So, what we do is, we create the RECT
    // struct for our window as follows:
    RECT rect;
    SetRect( &rect, 50,  // left
                    50,  // top
                    850, // right
                    650 ); // bottom
    
    // Save width and height off.
    g.width = rect.right - rect.left;
    g.height = rect.bottom - rect.top;
    
    // Adjust it.
    AdjustWindowRect( &rect, WS_OVERLAPPEDWINDOW, false );

    // AdjustWindowRect() expands the RECT
    // so that the CLIENT AREA (drawable region)
    // has EXACTLY the dimensions we specify
    // in the incoming RECT.

    // If you didn't just understand that, understand
    // this:  "you have to call AdjustWindowRect()",
    // and move on.  Its not THAT important, but its
    // good for the performance of your app.

    ///////////////////
    // NOW we call CreateWindow, using
    // that adjusted RECT structure to
    // specify the width and height of the window.
    g.hwnd = CreateWindow(TEXT("Philip"),
                          TEXT("GL WINDOW!"),
                          WS_OVERLAPPEDWINDOW,
                          rect.left, rect.top,  // adjusted x, y positions
                          rect.right - rect.left, rect.bottom - rect.top,  // adjusted width and height
                          NULL, NULL,
                          hInstance, NULL);

    // check to see that the window
    // was created successfully!
    if( g.hwnd == NULL )
    {
        FatalAppExit( NULL, TEXT("CreateWindow() failed!") );
    }

    // and show.
    ShowWindow( g.hwnd, iCmdShow );
    #pragma endregion

    #pragma region part 2 - Get DC of window we just made
    //2.  GET DC OF WINDOW, and keep it in our global
    //    variable g.  We will NOT release this DC
    //    until our app is about to exit.
    g.hdc = GetDC( g.hwnd );

    // If this keeping-DC-for-life-of-program-thing
    // disturbs you as much as it disturbed me,
    // GOOD LUCK in finding MS-based documentation to validate
    // this practice!  All examples I've seen and
    // Astle's OpenGL gaming book do it this way,
    // so. . . I suppose its ok.

    // One of the things I make sure to do is to specify
    // CS_OWNDC when I create the window,
    // so that Windows maintains a separate device context
    // for my application's window.

    // I haven't run into problems with this.  I don't
    // think you should either.
    #pragma endregion

    #pragma region part 3 - SET PIXEL FORMAT OF HDC
    //3.  SET PIXEL FORMAT OF HDC.
    //
    // We now have to set up the PIXELFORMAT
    // of our HDC.

    // A PIXEL FORMAT just describes the
    // "qualities" that each pixel in the 
    // window will have.  Do you want your
    // OpenGL app to use 24 bit color
    // ("true color" -- really high
    // quality!)?  Or 16 bit color (can look
    // a bit washed out)?

    // There are 3 substeps here:
    //    A> create the PFD and set it up to describe
    //       the pixel format we DESIRE (dream of having!)
    //
    //    B> call ChoosePixelFormat() to make windows
    //       choose us the ID of the appropriate pixel format that
    //       is CLOSEST to our dream pixel format.
    //
    //    C> Call SetPixelFormat() using the integer ID number
    //       that ChoosePixelFormat() returned to us in step B>

    // So let's do that:

    ////////////////////
    // A> CREATE PFD:
    PIXELFORMATDESCRIPTOR pfd = { 0 };  // create the pfd,
    // and start it out with ALL ZEROs in ALL
    // of its fields.

    // A good description of the PIXELFORMATDESCRIPTOR
    // struct is under the documentation
    // for the ChoosePixelFormat() function:
    // http://msdn2.microsoft.com/en-us/library/ms537556(VS.85).aspx

    // If you look at the docs, MANY of the fields
    // are "NOT USED" and REMAIN 0.
    
    // That should be something of a relief to you!
    // Look at the number of fields in this beast!

    // So we set only the fields of the pfd we care about:
    pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );    // just its size
    pfd.nVersion = 1;   // always 1

    pfd.dwFlags = PFD_SUPPORT_OPENGL |  // OpenGL support - not DirectDraw
                  PFD_DOUBLEBUFFER   |  // double buffering support
                  PFD_DRAW_TO_WINDOW;   // draw to the app window, not to a bitmap image

    pfd.iPixelType = PFD_TYPE_RGBA ;    // red, green, blue, alpha for each pixel
    pfd.cColorBits = 24;                // 24 bit == 8 bits for red, 8 for green, 8 for blue.
                                        // This count of color bits EXCLUDES alpha.

    pfd.cDepthBits = 32;                // 32 bits to measure pixel depth.  That's accurate!

    ///////////////////
    // B> Alright!  We've filled out the pfd
    // and it describes the way we want
    // our pixels to appear on the screen.
    // 
    // Now this next step is a little bit weird.
    // The thing is, there are only a couple of
    // dozen ACCEPTABLE pixel formats in existence.
    //
    // In other words, the system MIGHT NOT
    // be able to use a pixel format the likes
    // of which you have described in your
    // PIXELFORMATDESCRIPTOR.

    // What to do?? It would be awful annoying
    // to have to keep TRYING different
    // PIXELFORMATDESCRIPTORS until we found
    // one that actually WORKED on this system.

    // So MSFT has a better solution.

    // We'll make a call to a function called
    // ChoosePixelFormat().  ChoosePixelFormat()
    // will examine the PIXELFORMATDESCRIPTOR
    // structure that you send it, then it will
    // give you back an ID for the pixel format
    // that MOST CLOSELY MATCHES the pixel format you
    // SAID you wanted.

    int chosenPixelFormat = ChoosePixelFormat( g.hdc, &pfd );
    // what comes back from ChoosePixelFormat() is
    // an integer identifier for a specific pixel
    // format that Windows ALREADY knows about.
    // If you got 0 back, then there was an error.
    if( chosenPixelFormat == 0 )
    {
        FatalAppExit( NULL, TEXT("ChoosePixelFormat() failed!") );
    }

    char b[100];
    sprintf(b, "You got ID# %d as your pixelformat!\n", chosenPixelFormat);
    MessageBoxA( NULL, b, "Your pixelformat", MB_OK );
    
    /////////////////
    // C> So finally, we call SetPixelFormat() using the integer ID number
    // that ChoosePixelFormat() returned to us previously.
    int result = SetPixelFormat( g.hdc, chosenPixelFormat, &pfd );

    if (result == NULL)
    {
        FatalAppExit( NULL, TEXT("SetPixelFormat() failed!") );
    }
    // and that's all there is to setting
    // the pixel format!
    //////////
    #pragma endregion

    #pragma region part 4 - CREATE THE RENDERING CONTEXT
    //4.  CREATE RENDERING CONTEXT (HGLRC).

    // What's a rendering context?
    // Its the "surface" that OpenGL
    // will DRAW to.
    
    // The HGLRC will be created
    // such that it is COMPATIBLE
    // with the hdc.

    g.hglrc = wglCreateContext( g.hdc );
    // Created the rendering context
    // and saved handle to it in global 'g'.
    //
    // Wasn't that awfully easy to create
    // such a complicated sounding thing?
    ///////////////
    #pragma endregion

    #pragma region part 5 - CONNECT THE RENDERING CONTEXT WITH THE DEVICE CONTEXT OF THE WINDOW
    //5.  CONNECT THE RENDER CONTEXT (HGLRC)
    //    WITH THE DEVICE CONTEXT (HDC) OF WINDOW.
    wglMakeCurrent( g.hdc, g.hglrc );

    //
    // OPEN GL INIT COMPLETED!!
    ////////////////////////////
    #pragma endregion

    #pragma region message loop
    MSG msg;

    while( 1 )
    {
        if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
        {
            if( msg.message == WM_QUIT )
            {
                break;
            }
            
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
        else
        {
            //6.  DRAW USING OPENGL.
            // This region right here is the
            // heart of our application.  THE MOST
            // execution time is spent just repeating
            // this draw() function.
            draw();
        }
    }
    #pragma endregion

    //////////////
    // clean up
    #pragma region clean up
    // UNmake your rendering context (make it 'uncurrent')
    wglMakeCurrent( NULL, NULL );

    // Delete the rendering context, we no longer need it.
    wglDeleteContext( g.hglrc );

    // release your window's DC
    ReleaseDC( g.hwnd, g.hdc );
    #pragma endregion

    // and a cheesy fade exit
    AnimateWindow( g.hwnd, 200, AW_HIDE | AW_BLEND );

    return msg.wParam;
}

////////////////////////
// DRAWING FUNCTION
void draw() 
{
    // 1. set up the viewport
    glViewport(0, 0, g.width, g.height); // set viewport
    // to be the whole width and height
    // of the CLIENT AREA (drawable region) of the window,
    // (the CLIENT AREA excludes the titlebar and the 
    // maximize/minimize buttons).

    // 2. projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0,(float)g.width/(float)g.height, 1, 1000);

    // 3. viewing transformation
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(  0, 0, 10,
                0, 0, 0,
                0, 1, 0);

    // 4. modelling transformation and drawing
    glClearColor( 0.5, 0, 0, 0 );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    static float i = 0.01f;
    // Notice that 'i' is a STATIC variable.
    // That's very important. (imagine me saying
    // that like Conchords in "Business Time")
    // http://youtube.com/watch?v=WGOohBytKTU

    // A 'static' variable is created ONCE
    // when the function in which it sits first runs.
    
    // The static variable will "LIVE ON"
    // between seperate calls to the function
    // in which it lives UNTIL THE PROGRAM ENDS.

    i+= 0.001f;     // increase i by 0.001 from its
    // it had on the LAST FUNCTION CALL to the draw() function

    float c = cos( i );
    float s = sin( i );

    glBegin (GL_TRIANGLES);
        glColor3f(  c, 0, 0 );      // red
        glVertex3f( 1+c, 0+s, 0 );

        glColor3f(  c, s, 0 );      // yellow
        glVertex3f( 0+c, 1+s, 0 );

        glColor3f(  s, 0.1f, s );   // magenta
        glVertex3f(-1+c, 0+s, 0 );
    glEnd();

    //7.  SWAP BUFFERS.
    SwapBuffers(g.hdc);
    // Its important to realize that the backbuffer
    // is intelligently managed by the HDC ON ITS OWN,
    // so all's you gots to do is call SwapBuffers
    // on the HDC of your window.
}





////////////////////////
// WNDPROC
// Notice that WndProc is very very neglected.
// We hardly do anything with it!  That's because
// we do all of our processing in the draw()
// function.
LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 
{
    switch( message )
    {
    case WM_CREATE:
        Beep( 50, 10 );
        return 0;
        break;

    case WM_PAINT:
        {
            HDC hdc;
            PAINTSTRUCT ps;
            hdc = BeginPaint( hwnd, &ps );
                // don't draw here.  would be waaay too slow.
                // draw in the draw() function instead.
            EndPaint( hwnd, &ps );
        }
        return 0;
        break;

    case WM_KEYDOWN:
        switch( wparam )
        {
        case VK_ESCAPE:
            PostQuitMessage( 0 );
            break;
        default:
            break;
        }
        return 0;

    case WM_DESTROY:
        PostQuitMessage( 0 ) ;
        return 0;
        break;
    }
 
    return DefWindowProc( hwnd, message, wparam, lparam );
}



////////////////
// END NOTES:
//
// Some good references:
// WGL function ref on MSDN:
// http://msdn2.microsoft.com/en-us/library/ms673957%28VS.85%29.aspx

// MSDN example from 1994 (but still good!)
// "OpenGL I: Quick Start"
// http://msdn2.microsoft.com/en-us/library/ms970745.aspx


//////////////////
// QUICK Q&A (make sure you know what's going on):
//
// QUESTION:  What's the means by which we can draw
//            to our window itself?
//
// ANSWER:  The HDC (HANDLE TO DEVICE CONTEXT).

// QUESTION:  What's the means by which OpenGL can
//            draw to the window?
//
// ANSWER:  USING that SAME HDC WE woulda used
//          to draw to it!! (more to come on this now).

/////////////////////
// It IS possible to access the bits
// of the output of OpenGL in 2 ways:
//      1)  Use glReadPixels() to obtain
//          the arrayful of pixels on the
//          screen.  You can then save this
//          to a .TGA or .BMP file easily.

//      2)  Render to a BITMAP, then
//          blit that bitmap to your HDC.
//          There's a 1995 msdn article on this:
//          "OpenGL VI: Rendering on DIBs with PFD_DRAW_TO_BITMAP"
//          http://msdn2.microsoft.com/en-us/library/ms970768.aspx



/* 
     ____   __   __      __   __  ___
    / _  \ /  / /  /    /  /  \ \/  /
   / _/ / /  / /  /    /  /    \   /
  / _/ \ /  / /  /__  /  /__   /  /
 /_____//__/ /______//______/ /__/

*/

Download the Visual Studio 2005 project files hosted by esnips! (thanks esnips!)

Preventing or stopping the screensaver from going on from your C++ Windows program

To intercept the screensaver on Win32, you trap the WM_SYSCOMMAND message in your WndProc, then you check the value of wparam. SC_SCREENSAVE is the screensaver and SC_MONITORPOWER is that windowsy force that wants to shut off the monitor to save power.

To disable either, just return 0 from the event handler function under those cases.

Example:

// This is a piece of WNDPROC:
LRESULT CALLBACK WndProc(   HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) 
{
    switch( message )
    {
    .
    .
    .
        case WM_SYSCOMMAND:
        {
            // There is a system command
            // wparam has the exact command type that it is
            switch( wparam )
            {
                case SC_MOVE:
                    printf("You're moving the window!\n");
                    // don't interfere with this one, otherwise your window
                    // won't move normally when the user tries to move it!
                    break;

                case SC_SCREENSAVE:     // screensaver wants to begin
                    
                    return 0;           // returning 0 PREVENTS those things from happening
                    // Note about SC_SCREENSAVE:
                    // Try this.  Go into your settings and change
                    // your screensaver to start after 1 minute.
                    // Then run this program and sit and wait
                    // for the 1 minute.

                    // The funny thing about this, is Windows will
                    // keep trying to enter screen saver mode,
                    // by sending your app a "message" every
                    // half a second or so.

                    // If all you do is return 0; from this
                    // part, your app will keep on stopping
                    // the screensaver from starting.  And
                    // Windows will keep asking if it can
                    // start the screen saver or not, until
                    // the user does something to reset the
                    // screensaver-turn-on timer like move the mouse
                    // or press a key on the keyboard.

                    // if you wait even longer, the same thing
                    // happens with SC_MONITORPOWER, except
                    // you keep getting 2 messages now.
                    
                    case SC_MONITORPOWER:   // monitor wants to shut off - powersaver mode
                        return 0;           // returning 0 PREVENTS monitor from turning off
            } // end wparam inner switch
        } //end case WM_SYSCOMMAND
            .
            .
            .
    } // end switch(message)
} // end WndProc

MSDN is awkward to navigate. The cryptic URLs don’t help either.

Great tips page on catch22.net

This is a listing of refs that I don’t want to lose or spend time looking for again:



Straight msdn refs



RichText control Formatting text in a richedit control

Recommended books for Win32 programming:



Misc