トリッキーコードネット トップへ戻る   C/C++, Java, Perl, PHP, JavaScript, アルゴリズム, ショートコーディング, IOCCCコードの解説, 等々

サイト情報

トリッキーなコード

7行プログラミング

物凄いコード集

アルゴリズム

データ構造

C/C++な話題

コードサンプル

ツール/環境構築

開発ノウハウ 等

ネタ/ジョーク集

おススメ書籍/サイト

サイトTOP >> 7行プログラミング >> 砂嵐表示プログラミング - その4 (Win32API)

砂嵐プログラミング その4 (Win32API)

砂嵐プログラミング その3の続きです。

2種類の方法で、とうとう7行を達成しました~♪
(※ 2ちゃんねるに掲載されていた元コードのままでは、VC++2005でコンパイルエラーが発生した為、
    コンパイルが通る様、若干修正を加えてあります^^;)

7行砂嵐プログラミング - type1

#include <windows.h>
char*k,y[1<<20];int a=640,b=400,c,r,m[8];BITMAPINFO t={40,a,b,1,24};HWND g;int
WINAPI WinMain(HINSTANCE i,HINSTANCE,LPSTR,int){WNDCLASS w={67,DefWindowProc,0
,0,i,0,0,0,0,"T"};RegisterClass(&w);HDC v=GetDC(g=CreateWindow("T","砂",513<<19,
99,99,a,b,0,0,i,0));while(GetMessage((MSG*)m,g,0,0)!=-1){if(m[1]==15){for(k=y
;k<y+a*b*3;k+=3)*k=*(k+1)=*(k+2)=(r=r*9+5)>>16;SetDIBitsToDevice(v,0,0,a,b,0,0
,0,b,y,&t,0);}else DispatchMessage((MSG*)m);InvalidateRect(g,0,0);}return 0;}
適当にインデント・改行を入れて、見やすくしたものがこちら↓
#include <windows.h>
char * k, y[1<<20];
int a = 640, b = 400, c, r, m[8];
BITMAPINFO t = {40, a, b, 1, 24};
HWND g;

int WINAPI WinMain (HINSTANCE i, HINSTANCE, LPSTR, int)
{
    WNDCLASS w = {67, DefWindowProc, 0, 0, i, 0, 0, 0, 0, "T"};
    RegisterClass(&w);

    HDC v = GetDC(
                    g = CreateWindow("T","砂", 513 << 19, 99, 99, a, b, 0, 0, i, 0)
                );

    while (GetMessage((MSG*)m,g,0,0) != -1) {

        if (m[1] == 15) {
            for (k = y; k < y+a*b*3; k += 3)
                *k = *(k+1) = *(k+2) = (r=r*9+5) >> 16;

            SetDIBitsToDevice(v, 0, 0, a, b, 0, 0, 0, b, y, &t, 0);
        }
        else
            DispatchMessage((MSG*)m);

        InvalidateRect(g, 0, 0);
    }
    return 0;
}
ウィンドウクラス.styleの「67」は、「 CS_CLASSDC | CS_VREDRAW | CS_HREDRAW 」という意味です。 CS_CLASSDCを指定する理由は、ウィンドウクラスに所属するデバイスコンテキストを取得し、 メモリ解放の処理をしなくても、メモリがリークするのを防ぐためです。 (※ウィンドウクラスのスタイルに、 CS_CLASSDC, CS_OWNDC, CS_PARENTDC のいずれかを指定すると、 (デバイスコンテキストの取得時に、)ウィンドウクラスに所属する デバイスコンテキストのハンドルが取得されるらしいです。⇒ 詳細はMSDNを参照) そして、ウィンドウクラス.lpfnWndProcに DefWindowProcを指定し、 ウィンドウプロシージャをコーディングする手間を省きます。 GetMessage()のwhileループ内で、エラーではない場合(GetMessage()は、エラー時に-1を返します)、 砂嵐の描画処理を行います。 続いて、別のやり方↓↓

7行砂嵐プログラミング - type2

#include <windows.h>
HDC v;char*k,y[1<<20];int a=640,b=400,c,i,r,m[8];BITMAPINFO t={40,a,b,1,24};
HWND g;int WINAPI WinMain(HINSTANCE i,HINSTANCE,LPSTR,int){WNDCLASS w={67,
DefWindowProc,0,0,i,0,0,0,0,"T"};RegisterClass(&w);v=GetDC(g=CreateWindow("T",
0,268959744,0,0,a,b,0,0,i,0));for(;;){if(PeekMessage((MSG*)m,0,0,0,1))
DispatchMessage((MSG*)m);else{if(!IsWindow(g))return 0;for(k=y;k<y+a*b*3;k+=3)
*k=*(k+1)=*(k+2)=(r=r*9+5)>>16;SetDIBitsToDevice(v,0,0,a,b,0,0,0,b,y,&t,0);}}}
適当にインデント・改行を入れて、見やすくしたものがこちら↓
#include <windows.h>
HDC v;
char * k, y[1<<20];
int a = 640, b = 400, c, i, r, m[8];
BITMAPINFO t={40,a,b,1,24};
HWND g;

int WINAPI WinMain(HINSTANCE i, HINSTANCE, LPSTR, int)
{
    WNDCLASS w = {67, DefWindowProc, 0, 0, i, 0, 0, 0, 0, "1"};
    RegisterClass(&w);

    v = GetDC(
            g = CreateWindow("1", 0, 268959744, 0, 0, a, b, 0, 0, i, 0)
        );

    for (;;) {
        if (PeekMessage((MSG*)m,0,0,0,1))
            DispatchMessage((MSG*)m);
        else {
            if (!IsWindow(g))
                return 0;

            for (k = y; k < y+a*b*3; k += 3)
                *k = *(k+1) = *(k+2) = (r = r*9+5) >> 16;

            SetDIBitsToDevice(v, 0, 0, a, b, 0, 0, 0, b, y, &t ,0);
        }
    }
}
CreateWindow()の第3パラメータである「268959744」は、「WS_VISIBLE | WS_SYSMENU」と等価です。 また、PeekMessage()の第5パラメータである「1」は、「PM_REMOVE」と等価です (← winuser.h参照)。 さて、MSDNでPeekMessage関数について調べてみると、 PeekMessage()の第2パラメータにNULLを指定すると、 「PeekMessage()を呼び出した現在のスレッドに所属する任意のウィンドウに関連付けられているメッセージを取得します」 との事。 そして、PeekMessage()のBOOL型戻り値は、「成功/失敗」ではなく「メッセージ取得/未取得」であり、 WM_PAINTメッセージに関しては、PeekMessage()はメッセージキューから削除しないとの事です。 PeekMessage()のこれらの挙動から、上記のtype2コードが動作する仕組みが判明します^^;)
         このエントリーをはてなブックマークに追加   


作業効率化・ライフハックのオススメ記事




コンピュータ・テクノロジーのオススメ記事





恋愛・人間関係のオススメ記事




※ 当サイトは、トップページからリンクで辿る事の出来るページに限り、リンクフリーです。
※ 当サイトの閲覧/利用によって生じた如何なる損害も、当サイト管理人は責任を負いません。
※ 当サイトの内容を転載される場合は、当サイトへのリンクをお願い致します。