« 『神明宮』の『奉祝大祭』 | トップページ | 『さかなや道場』で飲んでみたよ♪ »

2009年10月20日 (火)

プログレスバーの中に文字を表示したい!

プログレスバーの中に文字を表示したい!

のでAPIを調べてみる…。

だがAPIでは、サポートされていないようだ…。

で、投げていた…。

所が、何か降って来て閃いた!

だったらプロシージャを乗っ取れば良いんじゃない?

それならフックかな?

てな訳で調べれてみた…。

そしたらサブクラス化にすれば良いじゃん!

って事が分かった…。

あ!サブクラス化を完全に忘れてた…。

ここまで来たら直ぐ出来るよ!

※ソースは『Microsoft Visual C++ 6.0』だよ。

//--------------------------------------
#pragma comment( lib, "comctl32.lib" )
//--------------------------------------
#include    <Windows.h>
#include    <CommCtrl.h>
//--------------------------------------
WNDPROC        OriginalProc;
//--------------------------------------
LRESULT CALLBACK ProgressBarProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    LRESULT    Result    = CallWindowProc( OriginalProc, hWnd, uMsg, wParam, lParam );
    if( uMsg == WM_PAINT )
    {
        LPSTR    String    = "push A button!";
        HDC    DC    = GetDC( hWnd );
        SetTextColor( DC, 0x00FFFFFF );
        SetBkMode( DC, TRANSPARENT );
        TextOut( DC, 0, 0, String, strlen( String ) );
        ReleaseDC( hWnd, DC );
    }
    return Result;
}
//--------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    static HWND        hProgress;
    switch( uMsg )
    {
    case WM_CREATE:
        InitCommonControls( );
        hProgress        = CreateWindowEx( 0, PROGRESS_CLASS, "", WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 40, 20, 200, 24, hWnd, 0, NULL, NULL );
        OriginalProc    = ( WNDPROC )SetWindowLong( hProgress, GWL_WNDPROC, ( LONG )ProgressBarProc );
        break;

    case WM_KEYUP:
        if( wParam == VK_ESCAPE )
        {
            DestroyWindow( hWnd );
        } else
        if( wParam == 'A' )
        {
            SendMessage( hProgress, PBM_SETRANGE, 0, MAKELPARAM( 0, 100 ) );
            for( int i = 0 ; i <= 100 ; i++ )
            {
                SendMessage( hProgress, PBM_SETPOS, i, 0 );
                Sleep( 10 );
            }
        }
        break;

    case WM_DESTROY:
        SetWindowLong( hProgress, GWL_WNDPROC, ( LONG )OriginalProc );
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, uMsg, wParam, lParam );
    }
    return 0;
}
//--------------------------------------
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow )
{
    LPSTR            name    = "sample";
    MSG                msg;
    HWND            hWnd;
    WNDCLASS        wc;

    memset( &wc, 0, sizeof( wc ) );
    wc.style            = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc        = WndProc;
    wc.hInstance        = hInstance;
    wc.hbrBackground    = ( HBRUSH )( COLOR_3DFACE + 1 );
    wc.lpszMenuName        =
    wc.lpszClassName    = name;
    RegisterClass( &wc );
    hWnd    = CreateWindow( name, name, WS_OVERLAPPEDWINDOW
, 100, 100, 290, 80, NULL, NULL, hInstance, NULL );
    ShowWindow( hWnd, nCmdShow );
    UpdateWindow( hWnd );
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    return( msg.wParam );
}

取り敢えず目的の第一弾は、達成した!

バーの重なる部分の文字の色変えやセンター合わせなど細工は第二段だね。

ここまで来たら後少し。

もうチョイ上等な処理は、こんな感じか?

//--------------------------------------
#pragma comment( lib, "comctl32.lib" )
//--------------------------------------
#include    <Windows.h>
#include    <CommCtrl.h>
//--------------------------------------
WNDPROC        OriginalProc;
char        ProgressBarText[30]    = "push A or B button!";
//--------------------------------------
#if 0
//    テキストだけ後付けの処理(比較用に用意)
LRESULT CALLBACK ProgressBarProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    LRESULT    Result    = CallWindowProc( OriginalProc, hWnd, uMsg, wParam, lParam );
    if( uMsg == WM_PAINT )
    {
        int        Length, X, Y, P, R;
        SIZE    Size;
        RECT    Rect, RectIn, RectOut;
        HRGN    RgnIn, RgnOut;
        HDC    hDC    = GetDC( hWnd );
        GetClientRect( hWnd, &Rect );
        // ※補正
        SetRect( &Rect, Rect.left + 1, Rect.top + 1, Rect.right    - 2, Rect.bottom - 1 );
        Length    = strlen( ProgressBarText );
        SetBkMode( hDC, TRANSPARENT );
        GetTextExtentPoint32( hDC, ProgressBarText, Length, &Size );
        X    = ( Rect.right - Size.cx ) / 2;
        Y    = ( Rect.bottom - Size.cy ) / 2;
        P    = SendMessage( hWnd, PBM_GETPOS, 0, 0 );
        R    = SendMessage( hWnd, PBM_GETRANGE, FALSE, 0 );
        P    = Rect.left + ( Rect.right - Rect.left ) * P / R;
        CopyRect( &RectIn, &Rect );
        CopyRect( &RectOut, &Rect );
        RectIn.right    = RectOut.left    = P;
        RgnIn    = CreateRectRgnIndirect( &RectIn );
        RgnOut    = CreateRectRgnIndirect( &RectOut );
        SetTextColor( hDC, 0x00FFFFFF );
        SelectClipRgn( hDC, RgnIn );
        TextOut( hDC, X, Y, ProgressBarText, Length );
        SetTextColor( hDC, 0x00000000 );
        SelectClipRgn( hDC, RgnOut );
        TextOut( hDC, X, Y, ProgressBarText, Length );
        ReleaseDC( hWnd, hDC );
    }
    return Result;
}
#else
//    ペイントを乗っ取って表示する処理
LRESULT CALLBACK ProgressBarProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    if( uMsg == WM_PAINT )
    {
        int        Length, X, Y, P, R;
        SIZE    Size;
        RECT    Rect, RectIn, RectOut;
        HRGN    RgnIn, RgnOut;
        PAINTSTRUCT    PaintStruct;
        HDC        hDC;
        hDC    = BeginPaint( hWnd, &PaintStruct );
        GetClientRect( hWnd, &Rect );
        // ※補正
        SetRect( &Rect, Rect.left + 1, Rect.top + 1, Rect.right    - 2, Rect.bottom - 1 );
        Length    = strlen( ProgressBarText );
        SetBkMode( hDC, TRANSPARENT );
        GetTextExtentPoint32( hDC, ProgressBarText, Length, &Size );
        X    = ( Rect.right - Size.cx ) / 2;
        Y    = ( Rect.bottom - Size.cy ) / 2;
        P    = SendMessage( hWnd, PBM_GETPOS, 0, 0 );
        R    = SendMessage( hWnd, PBM_GETRANGE, FALSE, 0 );
        P    = Rect.left + ( Rect.right - Rect.left ) * P / R;
        CopyRect( &RectIn, &Rect );
        CopyRect( &RectOut, &Rect );
        RectIn.right    = RectOut.left    = P;
        RgnIn    = CreateRectRgnIndirect( &RectIn );
        RgnOut    = CreateRectRgnIndirect( &RectOut );
        SetTextColor( hDC, 0x00FFFFFF );
        SelectClipRgn( hDC, RgnIn );
        FillRect( hDC, &RectIn, ( HBRUSH )COLOR_HIGHLIGHTTEXT );
        TextOut( hDC, X, Y, ProgressBarText, Length );
        SetTextColor( hDC, 0x00000000 );
        SelectClipRgn( hDC, RgnOut );
        TextOut( hDC, X, Y, ProgressBarText, Length );
        EndPaint( hWnd, &PaintStruct );
        return 0;
    }
    return CallWindowProc( OriginalProc, hWnd, uMsg, wParam, lParam );
}
#endif
//--------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    static HWND        hProgress;
    switch( uMsg )
    {
    case WM_CREATE:
        InitCommonControls( );
        hProgress        = CreateWindowEx( 0, PROGRESS_CLASS, "", WS_CHILD | WS_VISIBLE | PBS_SMOOTH, 40, 20, 200, 24, hWnd, 0, NULL, NULL );
        OriginalProc    = ( WNDPROC )SetWindowLong( hProgress, GWL_WNDPROC, ( LONG )ProgressBarProc );
        break;
    case WM_KEYUP:
        if( wParam == VK_ESCAPE )
        {
            DestroyWindow( hWnd );
        } else
        if( wParam == 'A' )
        {
            strcpy( ProgressBarText, "*********************" );
            InvalidateRect( hProgress, NULL, TRUE );
            SendMessage( hProgress, PBM_SETRANGE, 0, MAKELPARAM( 0, 100 ) );
            for( int i = 0 ; i <= 100 ; i++ )
            {
                SendMessage( hProgress, PBM_SETPOS, i, 0 );
                Sleep( 10 );
            }
        } else
        if( wParam == 'S' )
        {
            SendMessage( hProgress, PBM_SETRANGE, 0, MAKELPARAM( 0, 100 ) );
            for( int i = 0 ; i <= 100 ; i++ )
            {
                wsprintf( ProgressBarText, "** %3d", i );
                InvalidateRect( hProgress, NULL, TRUE );
                SendMessage( hProgress, PBM_SETPOS, i, 0 );
                Sleep( 10 );
            }
        }
        break;

    case WM_DESTROY:
        SetWindowLong( hProgress, GWL_WNDPROC, ( LONG )OriginalProc );
        PostQuitMessage( 0 );
        break;

    default:
        return DefWindowProc( hWnd, uMsg, wParam, lParam );
    }
    return 0;
}
//--------------------------------------
int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow )
{
    LPSTR            name    = "sample";
    MSG                msg;
    HWND            hWnd;
    WNDCLASS        wc;

    memset( &wc, 0, sizeof( wc ) );
    wc.style            = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc        = WndProc;
    wc.hInstance        = hInstance;
    wc.hbrBackground    = ( HBRUSH )( COLOR_3DFACE + 1 );
    wc.lpszMenuName        =
    wc.lpszClassName    = name;
    RegisterClass( &wc );
    hWnd    = CreateWindow( name, name, WS_OVERLAPPEDWINDOW
, 100, 100, 290, 80, NULL, NULL, hInstance, NULL );
    ShowWindow( hWnd, nCmdShow );
    UpdateWindow( hWnd );
    while( GetMessage( &msg, NULL, 0, 0 ) )
    {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
    return( msg.wParam );
}

出来てしまえば、出来なかった自分が阿保に思えるから不思議…。(汗)

ここまで出来れば、後はクラス化してまとめれば直ぐだ♪

サブクラス化を思い出せば直ぐだったなぁ~。

でも、また忘れそうなので記録しておこう!

|

« 『神明宮』の『奉祝大祭』 | トップページ | 『さかなや道場』で飲んでみたよ♪ »

コメント

           v(´∀`◎)

投稿: kouyou | 2015年10月 7日 (水) 00時07分

(◎´∀`)ノ

投稿: | 2015年10月 6日 (火) 16時36分

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/108365/46532539

この記事へのトラックバック一覧です: プログレスバーの中に文字を表示したい!:

« 『神明宮』の『奉祝大祭』 | トップページ | 『さかなや道場』で飲んでみたよ♪ »