「グローバル変数」を含む日記 RSS

はてなキーワード: グローバル変数とは

2019-02-07

anond:20190207110429

人間にとって大規模なシステムを書きやす言語として発達した概念は、

AIにとっては不要だもんね。

オールグローバル変数でも全くバグのないプログラムが書けるAIが開発されると、

AIにとって書きやす言語に取って代わられると思う。

2019-02-06

COBOLってこんな言語

日経xTECHの元記事を読んでもCOBOLの特徴があんまり伝わってこない感じだし、かといってそれをディスってもしょうがないので、書いてみた。

https://anond.hatelabo.jp/20190205192741

COBOL本質的にはDSLなんだけど、一見汎用プログラミング言語に見えてしまってRubyPythonなんかと比較するのが誤解のもとではあると思う。今の人でも知ってそうなCOBOLに似ている言語はたぶんSQLで、データを処理するための専用言語。ただ、SQLは頑張ればすごく複雑なこともできるパワフルな言語で、だからこそ現代でも生き延びているわけだけど、COBOLはわりとシンプルデータ処理を想定している感じ。

SQLだけでアプリケーションを作れないのは触ったことある人なら誰でもわかると思う。普通JavaRubyで全体の流れを記述してデータベース入出力をSQLで書く。COBOLもそんな感じで、全体の流れをJCLやShellスクリプト、あるいはJP1のような運用管理ソフトで書く。SQLの1個の処理に相当するのがCOBOLコンパイル単位で、それごとにソースファイルが分割される。ひとつソースファイルに2個以上の処理を書くこともできるけど普通はしない。ここまで理解すると古いCOBOLに1ファイル内のすべての処理に影響するグローバル変数しかないのや、今のCOBOLコンパイル単位をまたぐ真のグローバル変数がないのも、それほどクリティカルではないことがわかると思う。もし、本当に複数の処理にまたがる値が必要なら、データベースに格納してしまえばいいんだし。

で、SQLでいうところのデータベースに相当するのがCOBOLではデータファイルsedawkテキストファイルCSVファイルを行ごとに処理するのとちょっと似てるけど、COBOL場合は固定長ファイルという点が違う。改行文字は入ってなくて、たとえば150バイトごとに次のレコードみたいな形式。これの1レコードごとに何月何日何時に〇〇という商品を□□円で売ったとか書いてあるのが典型的データの内容。それを集計して今日は〇〇が何個売れて売上がどれだけあったとか、出金合計がいくらで入金合計がいくらで、みたいな財務諸表を作ったり。SQLと同じように税率なんかが書いてあるマスタデータと、日々の売り上げが書いてあるトランザクションデータがあって、突き合わせたりということもする。こういう集計処理だからUIはなくて、夜中に自動起動するようなバッチプログラムが主な使われ方。(混乱するから余談だけど、今のCOBOLSQLを使って普通RDBにもアクセスできる。ただ使い方としては、RDBファイル処理→ファイル処理→ファイル処理→ファイル処理→ファイル処理→RDBみたいに、最初最後だけみたいなのが普通

入出力がファイルから今の感覚で考えるとアクセスは遅い。でもメリットもあって、1回に1行しかメモリに乗せないからどんな巨大なデータでも時間さえかければ処理できる。それこそ国民ひとりひとりの年金データとかね。あと、途中でバグ不正データで止まってもデータを失うのは最小限で済むので復旧が比較的楽だったり。

データベースの話に戻ると、テーブル定義はどこに書いてあるかというとデータファイル側ではなくてCOBOLプログラム側、というのがSQLと一番違うところかも。つまり、このデータファイル構造はこれこれこうなっていると想定して読みます、とソースコードに自分で書く。当然実際のデータ構造がそれと違ってたらおかしくなる。

まあそんな感じで80年代くらいに会計処理をする目的だったら悪い言語ではなかったので、銀行官公庁とか、電力水道ガスといったライフラインを扱う大企業がこぞって導入して今に至る感じ。普通大企業は途中でSunかに置き換えてその後Linuxクラウドさらに置き換えたりしたけど、最初に作ったシステムが大きければ大きいほど、重要であれば重要であるほど現代的な環境に置き換えられないというのが今の課題

2019-02-05

COBOLer、人を呪わば穴2つ

リーナスですら自身攻撃発言自戒するこの時代、本邦の好戦的技術者を見てげんなりした話。

 

COBOLは難しいか、記者が試しにコードを書いてみた 」という記事日経XTECHに掲載された。はてブでも賑わいを見せている。

この記事では COBOL体験記者が OpenCOBOL という処理系FizzBuzz 問題を書き、それを踏まえて COBOL への評価と雑感が示されている。

これに対して、反論記事を見つけた。

 ま た 大 森 敏 行 か

タイトルからし技術批判というより個人攻撃主題にあり、すでに怪しげな雰囲気が出ている。

そんな雰囲気を交わしつつ途中までは「なるほど、COBOL特性データ構造にあり、件の記事では COBOL の特徴を捉えきれていないので結論勇み足だし的外れなのか…」と思っていた(私はCOBOL経験)。

けど、結語まで読んでげんなりしてしまう。

日経BPの記者ふぜいがgdgd言ったところでCOBOLはなくならない。それでいてこのようなFUD技術者敬遠させる効果はある。なくなりもしないのに技術者敬遠したら何が起きるか、わからない記者腹を切って死ぬべきである

日経記事的外れなのは分かったが、ここまでくると読んでて辛い(腹を切って云々はネットスラングだとしてもなんだかな)。

しかも、この人自身過去日経で連載を持っていて、それをプロフィールに書いている(!)のに個人宛じゃなくて日経BP記者ふぜいとか言っちゃうのか…。さら企業社長とのこと……

 

かなり本気で思ってるんで、日経ネットワークの当該記者コンタクト取って欲しいんだけど。 (「悪い大人」より)

あの語調で返されたらコンタクトを取りたがる人はあまりいないんじゃないかなぁー

 

この方、以前にはこんなことも言っていた(この際の批判対象の記事は私も問題があると思うが)。

まさにこれだった。いつの間にか、「オープンソース界」は英語hackマウンティングする奴等が力を持つようになってしまって、陳腐hacker集団に成り下がってしまったようだが。

まさに人を呪わば穴2つ。

 

---

ちなみに批判記事にある「(真の)グローバル変数」の話ですけど、へぇ勉強にはなった。

これは私が不安になったので確認ですけど、一般には「コンパイル単位内でのみグローバルな変数」もグローバル変数って呼びますよね?(ですよね?)

 

あと、"DATA DIVISION" の箇所についても「鶏を裂くに牛刀を持ち出す」という喩えを使うのにもなんか違和感がある。

というか COBOL では問題がなんであれ "DATA DIVISION" を使わざるえないのだったら、「鶏を裂くにも牛刀を持ち出さざるを得ない(だから鶏を捌くな)」のほうが適切なのでは…

COBOLer からすると前者の喩えで膝を打つ感じなんでしょうか?)

その後の「丸木橋経験本四架橋を論じる」の喩えはよくわかる。

2019-01-03

anond:20190103184241

// WindowsProject7.cpp: アプリケーションエントリ ポイント定義します。
//

#include "stdafx.h"
#include "WindowsProject7.h"

#define MAX_LOADSTRING 100

// グローバル変数:
HINSTANCE hInst;                                // 現在インターフェイス
WCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーテキスト
WCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名

// このコード モジュールに含まれ関数宣言転送します:
//ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

#include <list>

class MyWindow;
	
std::list< MyWindow *> windows;

class MyWindow
{
public:

	HWND hWnd;



	MyWindow()
		:hWnd(NULL)
	{
		windows.push_back(this);
	}

	virtual ~MyWindow()
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			if (*it == this)
			{
				windows.erase(it);
				break;
			}
		}
	}

	static MyWindow * find(HWND key)
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			MyWindow *target = *it;

			if (target->hWnd == key)
			{
				return target;
			}

		}

		return NULL;
	}



	//
	//  関数: MyRegisterClass()
	//
	//  目的: ウィンドウ クラス登録します。
	//
	ATOM MyRegisterClass(HINSTANCE hInstance)
	{
		WNDCLASSEXW wcex;

		wcex.cbSize = sizeof(WNDCLASSEX);

		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.lpfnWndProc = WndProc;
		wcex.cbClsExtra = 0;
		wcex.cbWndExtra = 0;
		wcex.hInstance = hInstance;
		wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7));
		wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7);
		wcex.lpszClassName = szWindowClass;
		wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

		return RegisterClassExW(&wcex);
	}

	//
	//   関数: InitInstance(HINSTANCE, int)
	//
	//   目的: インスタンス ハンドルを保存して、メイン ウィンドウ作成します。
	//
	//   コメント:
	//
	//        この関数で、グローバル変数インスタンス ハンドルを保存し、
	//        メイン プログラム ウィンドウ作成および表示します。
	//

	int blocks[100][100];

	BOOL InitInstance()
	{
		hInst = hInstance; // グローバル変数インスタンス処理を格納します。

		ATOM c = MyRegisterClass(hInstance);
		x = 0;
		y = 0;
		boxType = 0;

		hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

		for(int x = 0 ; x < 100 ; x++)
		{
			for (int y = 0; y < 100; y++)
			{
				blocks[y][x] = 0;
			}
		}

		if (!hWnd)
		{
			return FALSE;
		}

		return TRUE;
	}

	BOOL ShowWindow()
	{
		BOOL ret;
		ret = ::ShowWindow(hWnd, SW_SHOW);
		::UpdateWindow(hWnd);

		return ret;
	}


	HINSTANCE hInstance;
	MSG msg;
	BOOL run;
	int x;
	int y;
	BOOL Main()
	{

		HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7));
		run = true;
		int rc;
		// メイン メッセージ ループ:
		while (run)
		{
			DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL,  100 , QS_PAINT| QS_ALLEVENTS,0);
			if (obj <= WAIT_OBJECT_0)
			{
				while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
					if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
					{
						TranslateMessage(&msg);
						DispatchMessage(&msg);
					}
					if (msg.message == WM_QUIT) {
						run = FALSE;
					}
					if (msg.message == WM_CLOSE) {
						run = FALSE;
					}

				}
			}
			else if (obj == WAIT_TIMEOUT)
			{
				y++;
				PAINTSTRUCT ps;
				HDC hdc = BeginPaint(hWnd, &ps);
				this->OnPaint(ps);
				EndPaint(hWnd, &ps);
				::UpdateWindow(hWnd);
				RECT Rect2 = { 0,0,48*9,48 * 100 };
				InvalidateRect(hWnd, &Rect2, TRUE);
			}
			else if (obj == WAIT_FAILED)
			{
				rc = GetLastError();
			}
			else {

			}
		}


		return TRUE;

	}

	int boxType;

	BOOL WriteBoxOLDBox()
	{
		int width = 24;

		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 48));
		for (int y = 0; y < 30; y++)
		{
			for (int x = 0; x < 8; x++)
			{
				if (blocks[y][x] == 0)
				{
					continue;
				}

				RECT Rect = { 0,0,48,48 };
				BOOL ret;

				Rect.left = width * x + 1;
				Rect.right = width * (x + 1) - 1;
				Rect.top = width * y + 1;
				Rect.bottom = width * (y + 1) - 1;

				ret = FillRect(hdc, &Rect, hBrush);


			}
		}

		DeleteObject(hBrush);

		return FALSE;
	}


	BOOL WriteBox()
	{
		WriteBoxOLDBox();

		switch (boxType)
		{
		case 0:
			return WriteBoxI();
		case 1:
			return WriteBoxL();
		case 2:
			return WriteBoxZ();

		}

		return TRUE;
	}

	BOOL WriteBoxZ()
	{
		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246));

		int width = 24;

		RECT Rect = { 0,0,48,48 };
		BOOL ret;

		Rect.left = width * x + 1;
		Rect.right = width * (x + 1) - 1;
		Rect.top = width * y + 1;
		Rect.bottom = width * (y + 1) - 1;

		ret = FillRect(hdc, &Rect, hBrush);


		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.left += width;
		Rect.right += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);


		DeleteObject(hBrush);

		return TRUE;
	}


	BOOL WriteBoxL()
	{
		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 246 , 48));

		int width = 24;

		RECT Rect = { 0,0,48,48 };
		BOOL ret;

		Rect.left = width * x + 1;
		Rect.right = width * (x + 1) -1 ;
		Rect.top = width * y + 1;
		Rect.bottom = width * (y + 1) -1;

		ret = FillRect(hdc, &Rect, hBrush);


		Rect.top    += width; 
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.left   += width;
		Rect.right  += width;
		ret = FillRect(hdc, &Rect, hBrush);

		DeleteObject(hBrush);

		return TRUE;
	}

	BOOL WriteBoxI()
	{
		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB( 246 , 48 , 48));

		int width = 24;

		RECT Rect = { 0,0,48,48 };
		BOOL ret;

		Rect.left = width * x + 1;
		Rect.right = width * (x + 1) - 1;
		Rect.top = width * y + 1;
		Rect.bottom = width * (y + 1) - 1;

		ret = FillRect(hdc, &Rect, hBrush);


		//Rect.left   += width;
		//Rect.right  += width;
		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		DeleteObject(hBrush);

		return TRUE;
	}

	BOOL SaveBoxI()
	{
		blocks[y  ][x] = 1;
		blocks[y+1][x] = 1;
		blocks[y+2][x] = 1;
		blocks[y+3][x] = 1;
		return TRUE;
	}


	BOOL OnPaint(PAINTSTRUCT &ps)
	{
		if (x > 8) {
			x = 0;
		}
		if (x <0) {
			x = 8;
		}
		if (y > 20) {
			switch (boxType)
			{
			case 0:
				SaveBoxI();
				break;
			case 1:
				break;
			case 2:
				break;
			}

			y = 0;
			boxType++;
			if (boxType > 2)
			{
				boxType = 0;
			}
		}

		this->WriteBox();

		return TRUE;
	}



	BOOL OnKey(WPARAM wParam)
	{
		if (wParam == VK_LEFT)
		{
			x++;
		}
		if (wParam == VK_RIGHT)
		{
			x--;
		}
		return TRUE;
	}


};


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: ここにコードを挿入してください。

    // グローバル文字列初期化しています。
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING);
    //MyRegisterClass(hInstance);



	MyWindow win;



	win.hInstance = hInstance;

	// アプリケーション初期化を実行します:
	if (!win.InitInstance())
	{
		return FALSE;
	}

	BOOL ret;

	win.ShowWindow();

	ret = win.Main();

	if (ret)
	{
		return 0;
	}else {
		return (int)win.msg.wParam;
	}



}






//
//  関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    メイン ウィンドウメッセージを処理します。
//
//  WM_COMMAND  - アプリケーション メニューの処理
//  WM_PAINT    - メイン ウィンドウの描画
//  WM_DESTROY  - 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 選択されたメニューの解析:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
		break;
	case WM_KEYDOWN:
		{
			MyWindow *target = MyWindow::find(hWnd);
			target->OnKey(wParam);
		}
	break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

			MyWindow *target = MyWindow::find(hWnd);
			target->OnPaint(ps);


            // TODO: HDC を使用する描画コードをここに追加してください...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// バージョン情報ボックスメッセージ ハンドラーです。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

anond:20190103170543

テトリス

落ちてくるブロックの描き方

わかりやす関数化してみた

まずはブロックの種類は3種類

 

WriteBoxLとWriteBoxIとWriteBoxZ

の違いをよく見比べて

自力で違いがわかれば

プログラマーにはなれるとおもう

とはいえ、コレを自力でわかるならもっと儲かる仕事あるとはおもうけどな

 

	BOOL WriteBox()
	{
		switch (boxType)
		{
		case 0:
			return WriteBoxI();
		case 1:
			return WriteBoxL();
		case 2:
			return WriteBoxZ();

		}
	}
// WindowsProject7.cpp: アプリケーションエントリ ポイント定義します。
//

#include "stdafx.h"
#include "WindowsProject7.h"

#define MAX_LOADSTRING 100

// グローバル変数:
HINSTANCE hInst;                                // 現在インターフェイス
WCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーテキスト
WCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名

// このコード モジュールに含まれ関数宣言転送します:
//ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

#include <list>

class MyWindow;
	
std::list< MyWindow *> windows;

class MyWindow
{
public:

	HWND hWnd;



	MyWindow()
		:hWnd(NULL)
	{
		windows.push_back(this);
	}

	virtual ~MyWindow()
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			if (*it == this)
			{
				windows.erase(it);
				break;
			}
		}
	}

	static MyWindow * find(HWND key)
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			MyWindow *target = *it;

			if (target->hWnd == key)
			{
				return target;
			}

		}

		return NULL;
	}



	//
	//  関数: MyRegisterClass()
	//
	//  目的: ウィンドウ クラス登録します。
	//
	ATOM MyRegisterClass(HINSTANCE hInstance)
	{
		WNDCLASSEXW wcex;

		wcex.cbSize = sizeof(WNDCLASSEX);

		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.lpfnWndProc = WndProc;
		wcex.cbClsExtra = 0;
		wcex.cbWndExtra = 0;
		wcex.hInstance = hInstance;
		wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7));
		wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7);
		wcex.lpszClassName = szWindowClass;
		wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

		return RegisterClassExW(&wcex);
	}

	//
	//   関数: InitInstance(HINSTANCE, int)
	//
	//   目的: インスタンス ハンドルを保存して、メイン ウィンドウ作成します。
	//
	//   コメント:
	//
	//        この関数で、グローバル変数インスタンス ハンドルを保存し、
	//        メイン プログラム ウィンドウ作成および表示します。
	//
	BOOL InitInstance()
	{
		hInst = hInstance; // グローバル変数インスタンス処理を格納します。

		ATOM c = MyRegisterClass(hInstance);
		x = 0;
		y = 0;
		boxType = 0;

		hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

		if (!hWnd)
		{
			return FALSE;
		}

		return TRUE;
	}

	BOOL ShowWindow()
	{
		BOOL ret;
		ret = ::ShowWindow(hWnd, SW_SHOW);
		::UpdateWindow(hWnd);

		return ret;
	}


	HINSTANCE hInstance;
	MSG msg;
	BOOL run;
	int x;
	int y;
	BOOL Main()
	{

		HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7));
		run = true;
		int rc;
		// メイン メッセージ ループ:
		while (run)
		{
			DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL,  100 , QS_PAINT| QS_ALLEVENTS,0);
			if (obj <= WAIT_OBJECT_0)
			{
				while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
					if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
					{
						TranslateMessage(&msg);
						DispatchMessage(&msg);
					}
					if (msg.message == WM_QUIT) {
						run = FALSE;
					}
					if (msg.message == WM_CLOSE) {
						run = FALSE;
					}

				}
			}
			else if (obj == WAIT_TIMEOUT)
			{
				y++;
				PAINTSTRUCT ps;
				HDC hdc = BeginPaint(hWnd, &ps);
				this->OnPaint(ps);
				EndPaint(hWnd, &ps);
				::UpdateWindow(hWnd);
				RECT Rect2 = { 0,0,48*9,48 * 8 };
				InvalidateRect(hWnd, &Rect2, TRUE);
			}
			else if (obj == WAIT_FAILED)
			{
				rc = GetLastError();
			}
			else {

			}
		}


		return TRUE;

	}

	int boxType;

	BOOL WriteBox()
	{
		switch (boxType)
		{
		case 0:
			return WriteBoxI();
		case 1:
			return WriteBoxL();
		case 2:
			return WriteBoxZ();

		}
	}

	BOOL WriteBoxZ()
	{
		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246));

		int width = 24;

		RECT Rect = { 0,0,48,48 };
		BOOL ret;

		Rect.left = width * x + 1;
		Rect.right = width * (x + 1) - 1;
		Rect.top = width * y + 1;
		Rect.bottom = width * (y + 1) - 1;

		ret = FillRect(hdc, &Rect, hBrush);


		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.left += width;
		Rect.right += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);


		DeleteObject(hBrush);

		return TRUE;
	}


	BOOL WriteBoxL()
	{
		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246));

		int width = 24;

		RECT Rect = { 0,0,48,48 };
		BOOL ret;

		Rect.left = width * x + 1;
		Rect.right = width * (x + 1) -1 ;
		Rect.top = width * y + 1;
		Rect.bottom = width * (y + 1) -1;

		ret = FillRect(hdc, &Rect, hBrush);


		Rect.top    += width; 
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.left   += width;
		Rect.right  += width;
		ret = FillRect(hdc, &Rect, hBrush);

		DeleteObject(hBrush);

		return TRUE;
	}

	BOOL WriteBoxI()
	{
		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246));

		int width = 24;

		RECT Rect = { 0,0,48,48 };
		BOOL ret;

		Rect.left = width * x + 1;
		Rect.right = width * (x + 1) - 1;
		Rect.top = width * y + 1;
		Rect.bottom = width * (y + 1) - 1;

		ret = FillRect(hdc, &Rect, hBrush);


		//Rect.left   += width;
		//Rect.right  += width;
		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		Rect.top += width;
		Rect.bottom += width;
		ret = FillRect(hdc, &Rect, hBrush);

		DeleteObject(hBrush);

		return TRUE;
	}


	BOOL OnPaint(PAINTSTRUCT &ps)
	{
		if (x > 8) {
			x = 0;
		}
		if (x <0) {
			x = 8;
		}
		if (y > 8) {
			y = 0;
			boxType++;
			if (boxType > 2)
			{
				boxType = 0;
			}
		}

		this->WriteBox();

		return TRUE;
	}



	BOOL OnKey()
	{
		x++;
		return TRUE;
	}


};


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: ここにコードを挿入してください。

    // グローバル文字列初期化しています。
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING);
    //MyRegisterClass(hInstance);



	MyWindow win;



	win.hInstance = hInstance;

	// アプリケーション初期化を実行します:
	if (!win.InitInstance())
	{
		return FALSE;
	}

	BOOL ret;

	win.ShowWindow();

	ret = win.Main();

	if (ret)
	{
		return 0;
	}else {
		return (int)win.msg.wParam;
	}



}






//
//  関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    メイン ウィンドウメッセージを処理します。
//
//  WM_COMMAND  - アプリケーション メニューの処理
//  WM_PAINT    - メイン ウィンドウの描画
//  WM_DESTROY  - 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 選択されたメニューの解析:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
		break;
	case WM_KEYDOWN:
		{
			MyWindow *target = MyWindow::find(hWnd);
			target->OnKey();
		}
	break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

			MyWindow *target = MyWindow::find(hWnd);
			target->OnPaint(ps);


            // TODO: HDC を使用する描画コードをここに追加してください...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// バージョン情報ボックスメッセージ ハンドラーです。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

anond:20190101175055

テトリス風?プログラムに向けて

第何回だろうな

キー入力を追加した

まだ、何を押してもブロックが右に移動するだけ(右端にいくと左にワープ

タイマー自動落下

 

でもまぁ ここまでサンプルがあるとほぼテトリスは見えてきた

// WindowsProject7.cpp: アプリケーションエントリ ポイント定義します。
//

#include "stdafx.h"
#include "WindowsProject7.h"

#define MAX_LOADSTRING 100

// グローバル変数:
HINSTANCE hInst;                                // 現在インターフェイス
WCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーテキスト
WCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名

// このコード モジュールに含まれ関数宣言転送します:
//ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

#include <list>

class MyWindow;
	
std::list< MyWindow *> windows;

class MyWindow
{
public:

	HWND hWnd;



	MyWindow()
		:hWnd(NULL)
	{
		windows.push_back(this);
	}

	virtual ~MyWindow()
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			if (*it == this)
			{
				windows.erase(it);
				break;
			}
		}
	}

	static MyWindow * find(HWND key)
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			MyWindow *target = *it;

			if (target->hWnd == key)
			{
				return target;
			}

		}

		return NULL;
	}



	//
	//  関数: MyRegisterClass()
	//
	//  目的: ウィンドウ クラス登録します。
	//
	ATOM MyRegisterClass(HINSTANCE hInstance)
	{
		WNDCLASSEXW wcex;

		wcex.cbSize = sizeof(WNDCLASSEX);

		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.lpfnWndProc = WndProc;
		wcex.cbClsExtra = 0;
		wcex.cbWndExtra = 0;
		wcex.hInstance = hInstance;
		wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7));
		wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7);
		wcex.lpszClassName = szWindowClass;
		wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

		return RegisterClassExW(&wcex);
	}

	//
	//   関数: InitInstance(HINSTANCE, int)
	//
	//   目的: インスタンス ハンドルを保存して、メイン ウィンドウ作成します。
	//
	//   コメント:
	//
	//        この関数で、グローバル変数インスタンス ハンドルを保存し、
	//        メイン プログラム ウィンドウ作成および表示します。
	//
	BOOL InitInstance()
	{
		hInst = hInstance; // グローバル変数インスタンス処理を格納します。

		ATOM c = MyRegisterClass(hInstance);
		x = 0;
		y = 0;

		hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

		if (!hWnd)
		{
			return FALSE;
		}

		return TRUE;
	}

	BOOL ShowWindow()
	{
		BOOL ret;
		ret = ::ShowWindow(hWnd, SW_SHOW);
		::UpdateWindow(hWnd);

		return ret;
	}


	HINSTANCE hInstance;
	MSG msg;
	BOOL run;
	int x;
	int y;
	BOOL Main()
	{

		HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7));
		run = true;
		int rc;
		// メイン メッセージ ループ:
		while (run)
		{
			DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL,  100 , QS_PAINT| QS_ALLEVENTS,0);
			if (obj <= WAIT_OBJECT_0)
			{
				while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
					if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
					{
						TranslateMessage(&msg);
						DispatchMessage(&msg);
					}
					if (msg.message == WM_QUIT) {
						run = FALSE;
					}
					if (msg.message == WM_CLOSE) {
						run = FALSE;
					}

				}
			}
			else if (obj == WAIT_TIMEOUT)
			{
				y++;
				PAINTSTRUCT ps;
				HDC hdc = BeginPaint(hWnd, &ps);
				this->OnPaint(ps);
				EndPaint(hWnd, &ps);
				::UpdateWindow(hWnd);
				RECT Rect2 = { 0,0,48*9,48 * 8 };
				InvalidateRect(hWnd, &Rect2, TRUE);
			}
			else if (obj == WAIT_FAILED)
			{
				rc = GetLastError();
			}
			else {

			}
		}


		return TRUE;

	}

	BOOL OnPaint(PAINTSTRUCT &ps)
	{
		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246));
		RECT Rect = { 0,0,48,48 };
		Rect.left = 48 * x;
		Rect.right = 48 * (x+1);
		Rect.top = 48 * y;
		Rect.bottom = 48 * (y+1);
		if (x > 8) {
			x = 0;
		}
		if (x <0) {
			x = 8;
		}
		if (y > 8) {
			y = 0;
		}
		BOOL ret = FillRect(ps.hdc, &Rect, hBrush);
		DeleteObject(hBrush);

		return TRUE;
	}

	BOOL OnKey()
	{
		x++;
		return TRUE;
	}


};


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: ここにコードを挿入してください。

    // グローバル文字列初期化しています。
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING);
    //MyRegisterClass(hInstance);



	MyWindow win;



	win.hInstance = hInstance;

	// アプリケーション初期化を実行します:
	if (!win.InitInstance())
	{
		return FALSE;
	}

	BOOL ret;

	win.ShowWindow();

	ret = win.Main();

	if (ret)
	{
		return 0;
	}else {
		return (int)win.msg.wParam;
	}



}






//
//  関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    メイン ウィンドウメッセージを処理します。
//
//  WM_COMMAND  - アプリケーション メニューの処理
//  WM_PAINT    - メイン ウィンドウの描画
//  WM_DESTROY  - 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 選択されたメニューの解析:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
		break;
	case WM_KEYDOWN:
		{
			MyWindow *target = MyWindow::find(hWnd);
			target->OnKey();
		}
	break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

			MyWindow *target = MyWindow::find(hWnd);
			target->OnPaint(ps);


            // TODO: HDC を使用する描画コードをここに追加してください...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// バージョン情報ボックスメッセージ ハンドラーです。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

2019-01-01

anond:20190101172100

タイマーを使ったアニメーションを付けた

// WindowsProject7.cpp: アプリケーションエントリ ポイント定義します。
//

#include "stdafx.h"
#include "WindowsProject7.h"

#define MAX_LOADSTRING 100

// グローバル変数:
HINSTANCE hInst;                                // 現在インターフェイス
WCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーテキスト
WCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名

// このコード モジュールに含まれ関数宣言転送します:
//ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

#include <list>

class MyWindow;
	
std::list< MyWindow *> windows;

class MyWindow
{
public:

	HWND hWnd;



	MyWindow()
		:hWnd(NULL)
	{
		windows.push_back(this);
	}

	virtual ~MyWindow()
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			if (*it == this)
			{
				windows.erase(it);
				break;
			}
		}
	}

	static MyWindow * find(HWND key)
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			MyWindow *target = *it;

			if (target->hWnd == key)
			{
				return target;
			}

		}

		return NULL;
	}



	//
	//  関数: MyRegisterClass()
	//
	//  目的: ウィンドウ クラス登録します。
	//
	ATOM MyRegisterClass(HINSTANCE hInstance)
	{
		WNDCLASSEXW wcex;

		wcex.cbSize = sizeof(WNDCLASSEX);

		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.lpfnWndProc = WndProc;
		wcex.cbClsExtra = 0;
		wcex.cbWndExtra = 0;
		wcex.hInstance = hInstance;
		wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7));
		wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7);
		wcex.lpszClassName = szWindowClass;
		wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

		return RegisterClassExW(&wcex);
	}

	//
	//   関数: InitInstance(HINSTANCE, int)
	//
	//   目的: インスタンス ハンドルを保存して、メイン ウィンドウ作成します。
	//
	//   コメント:
	//
	//        この関数で、グローバル変数インスタンス ハンドルを保存し、
	//        メイン プログラム ウィンドウ作成および表示します。
	//
	BOOL InitInstance()
	{
		hInst = hInstance; // グローバル変数インスタンス処理を格納します。

		ATOM c = MyRegisterClass(hInstance);
		y = 0;

		hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

		if (!hWnd)
		{
			return FALSE;
		}

		return TRUE;
	}

	BOOL ShowWindow()
	{
		BOOL ret;
		ret = ::ShowWindow(hWnd, SW_SHOW);
		::UpdateWindow(hWnd);

		return ret;
	}


	HINSTANCE hInstance;
	MSG msg;
	BOOL run;
	int y;
	BOOL Main()
	{

		HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7));
		run = true;
		int rc;
		// メイン メッセージ ループ:
		while (run)
		{
			DWORD obj = MsgWaitForMultipleObjectsEx(0, NULL,  100 , QS_PAINT| QS_ALLEVENTS,0);
			if (obj <= WAIT_OBJECT_0)
			{
				while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
				{
					if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
					{
						TranslateMessage(&msg);
						DispatchMessage(&msg);
					}
					if (msg.message == WM_QUIT) {
						run = FALSE;
					}
					if (msg.message == WM_CLOSE) {
						run = FALSE;
					}

				}
			}
			else if (obj == WAIT_TIMEOUT)
			{
				y++;
				PAINTSTRUCT ps;
				HDC hdc = BeginPaint(hWnd, &ps);
				this->OnPaint(ps);
				EndPaint(hWnd, &ps);
				::UpdateWindow(hWnd);
				RECT Rect2 = { 0,0,48,48 * 8 };
				InvalidateRect(hWnd, &Rect2, TRUE);
			}
			else if (obj == WAIT_FAILED)
			{
				rc = GetLastError();
			}
			else {

			}
		}


		return TRUE;

	}

	BOOL OnPaint(PAINTSTRUCT &ps)
	{
		HDC hdc = GetDC(hWnd);
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246));
		RECT Rect = { 0,0,48,48 };
		Rect.top = 48 * y;
		Rect.bottom = 48 * (y+1);
		if (y > 8) {
			y = 0;
		}
		BOOL ret = FillRect(ps.hdc, &Rect, hBrush);
		DeleteObject(hBrush);

		return TRUE;
	}


};


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: ここにコードを挿入してください。

    // グローバル文字列初期化しています。
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING);
    //MyRegisterClass(hInstance);



	MyWindow win;



	win.hInstance = hInstance;

	// アプリケーション初期化を実行します:
	if (!win.InitInstance())
	{
		return FALSE;
	}

	BOOL ret;

	win.ShowWindow();

	ret = win.Main();

	if (ret)
	{
		return 0;
	}else {
		return (int)win.msg.wParam;
	}



}






//
//  関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    メイン ウィンドウメッセージを処理します。
//
//  WM_COMMAND  - アプリケーション メニューの処理
//  WM_PAINT    - メイン ウィンドウの描画
//  WM_DESTROY  - 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 選択されたメニューの解析:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

			MyWindow *target = MyWindow::find(hWnd);
			target->OnPaint(ps);


            // TODO: HDC を使用する描画コードをここに追加してください...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// バージョン情報ボックスメッセージ ハンドラーです。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

anond:20190101162210

やすいように フルソー

青い■を表示するだけ

// WindowsProject7.cpp: アプリケーションエントリ ポイント定義します。
//

#include "stdafx.h"
#include "WindowsProject7.h"

#define MAX_LOADSTRING 100

// グローバル変数:
HINSTANCE hInst;                                // 現在インターフェイス
WCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーテキスト
WCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名

// このコード モジュールに含まれ関数宣言転送します:
//ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

#include <list>

class MyWindow;
	
std::list< MyWindow *> windows;

class MyWindow
{
public:

	HWND hWnd;



	MyWindow()
		:hWnd(NULL)
	{
		windows.push_back(this);
	}

	virtual ~MyWindow()
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			if (*it == this)
			{
				windows.erase(it);
				break;
			}
		}
	}

	static MyWindow * find(HWND key)
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			MyWindow *target = *it;

			if (target->hWnd == key)
			{
				return target;
			}

		}

		return NULL;
	}



	//
	//  関数: MyRegisterClass()
	//
	//  目的: ウィンドウ クラス登録します。
	//
	ATOM MyRegisterClass(HINSTANCE hInstance)
	{
		WNDCLASSEXW wcex;

		wcex.cbSize = sizeof(WNDCLASSEX);

		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.lpfnWndProc = WndProc;
		wcex.cbClsExtra = 0;
		wcex.cbWndExtra = 0;
		wcex.hInstance = hInstance;
		wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7));
		wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7);
		wcex.lpszClassName = szWindowClass;
		wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

		return RegisterClassExW(&wcex);
	}

	//
	//   関数: InitInstance(HINSTANCE, int)
	//
	//   目的: インスタンス ハンドルを保存して、メイン ウィンドウ作成します。
	//
	//   コメント:
	//
	//        この関数で、グローバル変数インスタンス ハンドルを保存し、
	//        メイン プログラム ウィンドウ作成および表示します。
	//
	BOOL InitInstance()
	{
		hInst = hInstance; // グローバル変数インスタンス処理を格納します。

		ATOM c = MyRegisterClass(hInstance);


		hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

		if (!hWnd)
		{
			return FALSE;
		}

		return TRUE;
	}

	BOOL ShowWindow()
	{
		BOOL ret;
		ret = ::ShowWindow(hWnd, SW_SHOW);
		::UpdateWindow(hWnd);

		return ret;
	}


	HINSTANCE hInstance;
	MSG msg;

	BOOL Main()
	{

		HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7));

		// メイン メッセージ ループ:
		while (GetMessage(&msg, nullptr, 0, 0))
		{
			if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}


		return TRUE;

	}

	BOOL OnPaint(PAINTSTRUCT &ps)
	{
		HBRUSH hBrush = CreateSolidBrush(RGB(48, 48, 246));
		RECT Rect = { 0,0,48,48 };
		BOOL ret = FillRect(ps.hdc, &Rect, hBrush);
		DeleteObject(hBrush);

		return TRUE;
	}


};


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: ここにコードを挿入してください。

    // グローバル文字列初期化しています。
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING);
    //MyRegisterClass(hInstance);



	MyWindow win;



	win.hInstance = hInstance;

	// アプリケーション初期化を実行します:
	if (!win.InitInstance())
	{
		return FALSE;
	}

	BOOL ret;

	win.ShowWindow();

	ret = win.Main();

	if (ret)
	{
		return 0;
	}else {
		return (int)win.msg.wParam;
	}



}






//
//  関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    メイン ウィンドウメッセージを処理します。
//
//  WM_COMMAND  - アプリケーション メニューの処理
//  WM_PAINT    - メイン ウィンドウの描画
//  WM_DESTROY  - 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 選択されたメニューの解析:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

			MyWindow *target = MyWindow::find(hWnd);
			target->OnPaint(ps);


            // TODO: HDC を使用する描画コードをここに追加してください...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// バージョン情報ボックスメッセージ ハンドラーです。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

anond:20181231104029

// WindowsProject7.cpp: アプリケーションエントリ ポイント定義します。
//

#include "stdafx.h"
#include "WindowsProject7.h"

#define MAX_LOADSTRING 100

// グローバル変数:
HINSTANCE hInst;                                // 現在インターフェイス
WCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーテキスト
WCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名

// このコード モジュールに含まれ関数宣言転送します:
//ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

#include <list>

class MyWindow;
	
std::list< MyWindow *> windows;

class MyWindow
{
public:

	HWND hWnd;



	MyWindow()
		:hWnd(NULL)
	{
		windows.push_back(this);
	}

	virtual ~MyWindow()
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			if (*it == this)
			{
				windows.erase(it);
				break;
			}
		}
	}

	static MyWindow * find(HWND key)
	{
		std::list< MyWindow *>::iterator it;
		for (it = windows.begin(); it != windows.end(); it++)
		{
			MyWindow *target = *it;

			if (target->hWnd == key)
			{
				return target;
			}

		}

		return NULL;
	}



	//
	//  関数: MyRegisterClass()
	//
	//  目的: ウィンドウ クラス登録します。
	//
	ATOM MyRegisterClass(HINSTANCE hInstance)
	{
		WNDCLASSEXW wcex;

		wcex.cbSize = sizeof(WNDCLASSEX);

		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.lpfnWndProc = WndProc;
		wcex.cbClsExtra = 0;
		wcex.cbWndExtra = 0;
		wcex.hInstance = hInstance;
		wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7));
		wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7);
		wcex.lpszClassName = szWindowClass;
		wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

		return RegisterClassExW(&wcex);
	}

	//
	//   関数: InitInstance(HINSTANCE, int)
	//
	//   目的: インスタンス ハンドルを保存して、メイン ウィンドウ作成します。
	//
	//   コメント:
	//
	//        この関数で、グローバル変数インスタンス ハンドルを保存し、
	//        メイン プログラム ウィンドウ作成および表示します。
	//
	BOOL InitInstance()
	{
		hInst = hInstance; // グローバル変数インスタンス処理を格納します。

		ATOM c = MyRegisterClass(hInstance);


		hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

		if (!hWnd)
		{
			return FALSE;
		}

		return TRUE;
	}

	BOOL ShowWindow()
	{
		BOOL ret;
		ret = ::ShowWindow(hWnd, SW_SHOW);
		::UpdateWindow(hWnd);

		return ret;
	}


	HINSTANCE hInstance;
	MSG msg;

	BOOL Main()
	{

		HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7));

		// メイン メッセージ ループ:
		while (GetMessage(&msg, nullptr, 0, 0))
		{
			if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}


		return TRUE;

	}

	BOOL OnPaint()
	{
		return TRUE;
	}


};


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: ここにコードを挿入してください。

    // グローバル文字列初期化しています。
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING);
    //MyRegisterClass(hInstance);



	MyWindow win;



	win.hInstance = hInstance;

	// アプリケーション初期化を実行します:
	if (!win.InitInstance())
	{
		return FALSE;
	}

	BOOL ret;

	win.ShowWindow();

	ret = win.Main();

	if (ret)
	{
		return 0;
	}else {
		return (int)win.msg.wParam;
	}



}






//
//  関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    メイン ウィンドウメッセージを処理します。
//
//  WM_COMMAND  - アプリケーション メニューの処理
//  WM_PAINT    - メイン ウィンドウの描画
//  WM_DESTROY  - 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 選択されたメニューの解析:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);

			MyWindow *target = MyWindow::find(hWnd);
			target->OnPaint();


            // TODO: HDC を使用する描画コードをここに追加してください...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// バージョン情報ボックスメッセージ ハンドラーです。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}


Windowsシステムは基本 グローバル関数なので

グローバル関数<>クラス化されたメソッド

ブリッジ関数を書いた

2018-12-31

anond:20181228211250

// WindowsProject7.cpp: アプリケーションエントリ ポイント定義します。
//

#include "stdafx.h"
#include "WindowsProject7.h"

#define MAX_LOADSTRING 100

// グローバル変数:
HINSTANCE hInst;                                // 現在インターフェイス
WCHAR szTitle[MAX_LOADSTRING];                  // タイトル バーテキスト
WCHAR szWindowClass[MAX_LOADSTRING];            // メイン ウィンドウ クラス名

// このコード モジュールに含まれ関数宣言転送します:
//ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);


class MyWindow
{
public:

	HWND hWnd;

	MyWindow()
		:hWnd(NULL)
	{

	}


	//
	//  関数: MyRegisterClass()
	//
	//  目的: ウィンドウ クラス登録します。
	//
	ATOM MyRegisterClass(HINSTANCE hInstance)
	{
		WNDCLASSEXW wcex;

		wcex.cbSize = sizeof(WNDCLASSEX);

		wcex.style = CS_HREDRAW | CS_VREDRAW;
		wcex.lpfnWndProc = WndProc;
		wcex.cbClsExtra = 0;
		wcex.cbWndExtra = 0;
		wcex.hInstance = hInstance;
		wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT7));
		wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
		wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
		wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT7);
		wcex.lpszClassName = szWindowClass;
		wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

		return RegisterClassExW(&wcex);
	}

	//
	//   関数: InitInstance(HINSTANCE, int)
	//
	//   目的: インスタンス ハンドルを保存して、メイン ウィンドウ作成します。
	//
	//   コメント:
	//
	//        この関数で、グローバル変数インスタンス ハンドルを保存し、
	//        メイン プログラム ウィンドウ作成および表示します。
	//
	BOOL InitInstance()
	{
		hInst = hInstance; // グローバル変数インスタンス処理を格納します。

		ATOM c = MyRegisterClass(hInstance);


		hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
			CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

		if (!hWnd)
		{
			return FALSE;
		}

		return TRUE;
	}

	BOOL ShowWindow()
	{
		BOOL ret;
		ret = ::ShowWindow(hWnd, SW_SHOW);
		::UpdateWindow(hWnd);

		return ret;
	}


	HINSTANCE hInstance;
	MSG msg;

	BOOL Main()
	{

		HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT7));

		// メイン メッセージ ループ:
		while (GetMessage(&msg, nullptr, 0, 0))
		{
			if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}


		return TRUE;

	}



};


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: ここにコードを挿入してください。

    // グローバル文字列初期化しています。
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_WINDOWSPROJECT7, szWindowClass, MAX_LOADSTRING);
    //MyRegisterClass(hInstance);



	MyWindow win;



	win.hInstance = hInstance;

	// アプリケーション初期化を実行します:
	if (!win.InitInstance())
	{
		return FALSE;
	}

	BOOL ret;

	win.ShowWindow();

	ret = win.Main();

	if (ret)
	{
		return 0;
	}else {
		return (int)win.msg.wParam;
	}



}






//
//  関数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    メイン ウィンドウメッセージを処理します。
//
//  WM_COMMAND  - アプリケーション メニューの処理
//  WM_PAINT    - メイン ウィンドウの描画
//  WM_DESTROY  - 中止メッセージを表示して戻る
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 選択されたメニューの解析:
            switch (wmId)
            {
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: HDC を使用する描画コードをここに追加してください...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// バージョン情報ボックスメッセージ ハンドラーです。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

こんなかんじ。クラス化した

2018-11-26

コード見るのが一番の判断基準だと思う

ITエンジニアで、割とすごいと思っていた上司がいる

本人の話ではできそうな人だった


あるときその人の作ったものを引き継ぐ事があったのだけど、コードゴミのようだった

よくこれで動くなというかメンテしてきなっていうレベル


当たり前のようにグローバル変数を使うし、どこで最初に代入されるかも全コードgrep書けないとわからない

関数化もせずコピペが多い

mapやreduceみたいなものは一切使わず繰り返しはすべてfor文


本気でコードは捨てて仕様に基づいて1から作り直したほうがいいレベル


変に速度にこだわって、そんなの誰も気にしないってレベルのことにまで文句つけてくるくらいだから最適化の結果関数はインライン化して使い捨て変数はなしでグローバルを使うとかやってるのかと好意的に考えようともした

しかし、見ていると、その辺のwebページコピペがそのままコードに残ってるし、そういうところはインデントも揃ってなくてグチャグチャ

タブとスペースの混在も当たり前

あれこれ試した結果が見えるコードコメントアウトは全部残っている

単に能力無いようにしか見えない


それでも一応なにかそれなりのものを作れてしまうのが悪いところなんだと思う

趣味でやる分にはそういうので動くのはいいと思うが、仕事でそういうのはホントやめてほしい

ずっと一人で作っていて他の人と変わらないでもらいたい

昔はそこそこあった尊敬度もいまではマイナス、見下す対象しかならない



ということがあって、採用とかしてる人は本人が何作ったとか何使えるとか言っても、ちゃんコードみて能力判断したほうがいいと思った

外面のいいものが作れても中身がボロボロものが長く使えるとは思わないし、チームで作業するなら邪魔なだけ

特にキレイに書いたり修正やすものパフォーマンス落とすだけとか時間無駄って考えてるようだからどうしようもない

2018-10-25

Excelのいい感じの運用方法わからん

中小IT企業につきブラックボックス化は避けたいのでExcelを使う

関数の処理量とテーブルの扱いやすさを天秤に掛けつつ高速化を図る

VBAかいうのは極力使わない (Office2019など当然導入されない) (だいたいWindows10ですらない)

そこそこの期間の運用を想定しているのである程度の拡張性は欲しい

設定用シートを作ってグローバル変数を扱うように管理する方法などが王道だろうがあまりやりたくない

具体的な関数の使い方などの情報は腐るほどあるけどブックの構成にまで踏み込んでいるものは少ない

所詮使い捨てという気分でやるのが通常であり実用の上でも結果的によろしい効果をもたらすのかもしれない

2018-09-13

仕事では完璧にしようとか考えず動く程度に適当に作ればいい

面倒な上司がいろいろ文句をつけてくる

意味不明ものが多いし何かとケチつけないと気がすまない性格から面倒なことを一々と

直接のユーザから意見なら多少は変でもそのユーザ必要としてるなら納得できるし、イライラすることもない

依頼があったわけでもないのに謎の基準文句をつけてくる

社内でそんなことこだわったところで実際には気にされないことが多いのにだ

まだデザイナーデザインについてこうした方がUXいいねみたいなことをいうならわかる

専門の人の意見だし

そうでもないのに何かと文句をつけてくる

増田なのでwebで例をだそう

CSS すらまともに使いこなせずマージンもパディングもないような酷い作りのものしか作らないのにソッチのほうが良いという

色は red, green, yellow と標準のペイントのデフォルトカラーかよというような色を指定してくる

#fcfcfc や #0a0a0a なんて使おうものなら白と黒しろ

max-width を指定せずに画面の端から端まであるようなものがいいという

そのわりにグラデーション無意味につけたがる

一部例じゃなく本音が出たがまぁいいか

今の時代アプリサービスを全く見てないのか?としか言えないようなセンス

自社サービスなんて手を出したらこれは酷いと話題になりそうなもの

見た目にあまりこだわれない社内用サービスしか作ってないからと言って、その他サービスをみてる人からすれば明らかに

残念なしか時代遅れなものが良いと思ってる

しかデザインに限ったことではないがまだ序盤の時点で言っておけばいいものの完成後にいまから変えるなんて難しいのが

わかりきってるようなときになってからああしろこうしろ言い出す

先に書いたようにユーザ要望ならまだ仕方ないと言えるがなぜこんな無意味なことに付き合わなければならないのか


わりと自分完璧主義なところもあるので作るならちゃんと作ろうとしてるんだが

こういうのを相手にしないといけないせいで結局グチャグチャになってくる

色のバランスレイアウトを考えたところで一瞬でそのバランス無意味になるようなことになる

プログラムだって全然関係ないものを無理やり入れ込まないといけないようなことになることも多い

疎結合だとかグローバルをつかわないとかそういう作りやすくするためのことをしていても

それが維持できないような無茶で無意味な指示が出る

根本的に変えたり対処するためのものを作るとかすればなんとかできなくはない

しかしそんな時間はないので結局ひどい作りになるしかない

過去プロジェクトでもそういうのが多いか自分で作るのくらいは扱いやすくしたいと考えていたのだが

過去のもこういう経緯で酷いものになっていったのかなと思う


過去に言われたものだと速度を優先だとか言って自分で作ったものよりは遅くするなと言う

そしてそのコードは本人でしか読めないような酷いものだった

しかしながら関数は使わずコピペだわforeachなどは使わずループ変数を使って地道にやるなどメンテナンス

できる気がしないが速度においては早いと言えるもの

当たり前のようにグローバル変数がいっぱいあるしライブラリ使用箇所はカスタマイズするための仕組みがあるのに

ライブラリ自体をどんどん書き換えていく

便利で読みやすいような書き方だと速度的にはそれに劣る

だがわざわざそんな扱いづらいし見づらいコードは書きたくない

そんなに速度にこだわるなら勝手に一人で機械語でも書いてろよって思う

しかし速度に加えてメンテやすしろという

どちらか取捨選択すべきものなのに両方みたせとか無理なことを言う

ちなみに便利なライブラリは基本無駄が多い遅いものからライブラリ頼みのベンダはクソだとか

能力がないだとか言っていた


そういえば昔先輩社員仕事したときには変に凝ったものとか必要以上に作り込んだりはしないほうがいいとか

言っていてそれなりに手抜きでさらっと一応は動くようなものを作っていた

私はそういうやり方が嫌いだったのだが今ではこういう環境に長くいた結果仕事のものにこだわって作り込んでも無駄

ということがわかってそうなったのかなと感じた

自分でもサビ残休日無償出勤してまでいいものにしようと努力はしていたが謎の指摘に合わせていると

愛着もなくなってきたし後は適当に済ませてしまおうかなという気持ち

ちゃんとした自分なりの完璧ものを作ろうとするなら仕事ではなく趣味で作ってるツールライブラリ

やればいいかと思う


作ったもの次第でユーザが集まる自社のウェブサービスパッケージ商品ゲームなどは作り込む方が

良いと思うが先に値段が決まって受注して作るようなものだと最低限の要望さえ満たしていればあとは

どうでもいい

しろ不便な方が改修依頼が来て稼げる

さらには綺麗で完璧な作りで大抵の想定できる改修は1日とかからないようなものに仕上げるよりも

どこ変えればいいかや影響範囲すらわからいくらいモノのほうが実作業時間が多いのでそれだけ請求できる

先に作り込むメリットがない


ストレスが溜まってきたので発散がてら書いてみたけど疲れてるのかわりと分かりづらい文章になった

けどまぁいいか

そろそろ転職でもしたいなーと考え始めた










2018-09-07

python pandas でのソフトウェア開発

複数データを読み取り pandas で加工して excel に出力する、ということをしている。

pandas だとテストが書きにくいと思い、jupyter を使いながら普通python コード(a.py とする)を開発している。

以下のようなサイクルで開発を行なっている。a.py でクラス関数をある程度書いたらjupyter にimport して挙動確認し、間違っていたら jupyter でプロトタイプ的なコードを作り a.py に変更を加える。その後、jupyter のプロトタイプ的なコードは消して、jupyter をリスタートし上手くいっていることを確認する。そして、また次の機能確認に移る。

メリットは、

・pandas の挙動確認できる

問題としては、

・jupyter で最初からリスタートすると 5 秒くらいかかり、遅いなと思う。

・jupyter ってそもそも開発するのに向いていないのではないか、と思う。自分が慣れてないだけかもしれない。

何か良い知見があれば教えて下さい。

追記

id:houyhnhm

クラス関数定義し直すときは、どんどん下に新たな定義を書いていくってことですか?一手間へるけど行数は増えそう。あとは、グローバル変数がめちゃくちゃ増えるから管理に注意しないといけなさそうですね。

2018-07-11

anond:20180711162801

学生時代UNIXC言語を独学していた頃。

ちょっとした事(たしかグローバル変数ローカル変数挙動の違いとか、そんな事だったと思う)を試してみようと思って、20行くらいのプログラムを作ったんだ。

でも、動かないの。

どんな短いプログラムでも意図しない挙動をしてしまうことはあるものだが、そんなレベルの話ではない。

ただ、計算した結果を画面に出すだけのつもりなのに、何も表示されないんだ。

で、少しずつコメントアウトしていったのに、それでも何も表示されない。

しまいには、"A" って画面に出すだけのコードになったのに、それでも何も表示されないんだ。

(この日記言及先を見れば、ネタは一目瞭然なんだろうけど)


で、もう一本別のコードtest2.c という名前で作ったら、ちゃんと "A" と表示された。

一番始めに作ったコードも、すんなり動いた。


そうさ。最初コードtest.c という名前で作ったのだ。

から、できた実行ファイルtest

カレントディレクトリ よりも先に /bin に PATH が通っていたので 、単に test と打つと、 /bin/test が実行されていたんだ。

2018-04-10

anond:20180410165141

引数禁止。全部グローバル変数で渡せ」

えー、グローバル変数変わるタイミング分かりづれー

サブルーチンを使うとあちこちに飛んでわかりにくい。同じ処理をするときコピペでそれぞれの場所に同じコードを書きなさい」

むかーし、「ふんどしプログラム」って呼ばれてたやつか。

サブルーチン無しのメインだらだら書くやつ。

プロジェクトで開発した事無い奴らなのか?

それともそのプロジェクトで失敗して変に原点回帰しようとしてるのか?

何れにしても悲惨現場だな。

anond:20180409181511

サブルーチンに値を引数で渡してたら「引数禁止。全部グローバル変数で渡せ」とか、「サブルーチンを使うとあちこちに飛んでわかりにくい。同じ処理をするときコピペでそれぞれの場所に同じコードを書きなさい」とか言われたことがあるわ。

そこまでひどくなくてもレヴューを受けると「うわ、こいつレベル低っ」「この人Excelばっかりでコードいたことないんだろうな」みたいな人ばっかり。

レビュー機能してる現場に遭遇したことない。

2018-03-30

anond:20180330155333

A→B→C→D→Eってメソッドの流れ作ってるのに

途中だけ使われたり乱入されたり、グチャグチャにされることがある

メソッド呼び出しの流れに、作成者意図した順番があって、途中だけ呼ばれるとぐちゃぐちゃになるって、グローバル変数状態管理してる系のクソプログラム臭いがするんだが…

2017-07-26

今動いているアプリはみんな「元社員の成分」でできている

変な名前グローバル変数とか、

/* なぜか動いている */ とか、

どう考えても順番がおかしファイル出力とか

もう指摘することもできない

見つけるたびに「マジかー」と叫ぶ

2017-06-14

Golang勉強3日目ぐらいで疑問に思っている事

これは将来Golangに慣れて来た頃に読み返すメモです

学習してから3日目ぐらいだけど連続3日でやったとは言っていない。

学習時間は24時間にも満たないと思う。

モチベーションが上がった時に学習する程度。

公式チュートリアルをやってるけどやった箇所は忘れた。

英語版日本語版があるけど日本語版情報が古くないか不安

まだ半分ぐらいしかやってないけど良チュートリアルだと思う。

他のプログラミング言語と違ってチュートリアルの内容が足りないってこともなさそうだし、Golangチュートリアルだけは繰り返しやったほうが良さそう。

からGolangを学ぶならGoogleリポジトリにあるパッケージ管理depを使うほうが安心する。

まだ公式ツールじゃないけど将来なるかもしれないしならないかもしれない。

Googleのことだからgxuiみたいに更新されなくなる危険もあるよな・・・

でもプロジェクト新規作成するときrails new helloに相当するコマンドがないので不便。

スケルトン生成ツールが別途必要だけどフォルダ作るだけだからbatファイル用意するだけで良さそう。

あとGOPATHの設定もか。今のところは手動でやってるけどそのうちbatファイルにしたい。

Golang自体シンプル言語だと思う。

でもやりたいことができないのがつらい。

Rubyみたいにcursesが標準で使えない。

RubyみたいにTKも標準で使えない。

cursesぐらいは標準で出来て欲しいよ。

から他の言語はいらないのにGolangではそんなことでもライブラリを探してきてインストールしないといけない。

開発環境にはGoglandかVimがいい。

Goglandだとそのままでも十分だけどVim場合vim-goを入れるのが良い。

勉強会に参加するときは軽量ノートを持っていくので動作が軽いVimがいい。

でもryzen搭載ノートが来たらIDEに乗り換えるかもしれない。

コマンドラインツールを作るならGolangが一番簡単

cliってライブラリもあるみたいだけど標準機能flagだけで十分便利。

学習3日目でもflagの使い方は楽勝だった。

今の所もあんまりコマンドラインツールに興味ないので難しいことはしない。

とりあえず2ちゃん質問するのが良さそうだけど過疎だった。

過疎ってことはあんまり人気がない?

まだ質問するぐらい基礎的なもの学習してないけど。

やりたいことをぐぐってコピペしてる程度なのでdeferとかgo funcとかグローバル変数とか基礎的な部分はまだ知らない。

インストールが楽だけどWindows作ったらMacでも動くかは謎。

Mac mini買ってから試したい。

でもMacって高いから多分買わないと思う。

MacハードウェアしかMacOSインストールできないライセンスからWindows PCMacインストールできないかapple嫌い。

初心者だけどMac持ってる奴apple信者キモ杉と言わせてくれ

2017-04-11

http://anond.hatelabo.jp/20170410230648

頭の良い奴がプログラミングできない理由3つ

  1. 頭が良いとある程度大きなプログラムも頭の中で描けてしまい、構造プログラミングとかの意味理解できないので、グローバル変数ありきで作ったり、モジュールの切り分け方針おかしくて早晩行き詰まる
  2. 頭が良いとプログラミングなんてIT土方仕事だと1瞬で見抜けるため、さっさと逃げ出す
  3. 頭が良いと金暴力セックスという人生の真理にとっくにたどり着いているため、プログラミングなんかやるわけない

2017-02-26

httphttp://anond.hatelabo.jp/20170226153940anond.hatelabo.jp/20170226153940

言語仕様上、マルチバイト文字変数名に利用できる場合でも、変数名は半角英数字を使う。

グローバル変数はなるべく使わない。

・1関数に100行以上書かない。

主に、PHP使ってる。

2017-01-20

うちの会社プログラマが糞すぎる

できるプログラマもいるのだが、あまりにも糞なやつが多いので吐きださせてもらう。

1.遅刻常習犯

月曜日遅刻率が高すぎる奴がいる

2.ホウレンソウがない

社会人常識だろう。

進捗状況の報告がない。

定義仕様勝手想像して作り、報告しない。

挙げ句、その仕様おかしいと指摘すると不機嫌になる。

定義の時点で、簡単でいいから報告してくれるといいのだが。

3.設計センスがない

せめてDBの初期設計正規化してほしい。

外部キーとか夢のまた夢。

4.プログラムセンスがない

1000行越えのメソッドが大量にあったり、

オブジェクト指向言語なのにほとんどが静的メソッドだったり、

妙なグローバル変数があったり、

コードクローンが大量だったり。

5.テストしない

一度動かせばエラーが出るのにやらない

6.既存コード理解しない

コード意図理解しない。

結果、修正を行うつもりが、壊している。

上司よ。はやくメンバー入れ換えてくれ。

2017-01-09

プログラミングの勘所

プログラミングの入門者には伝統的に変数やif文、for文などが教えられてきました。

昨今ではJavaやってGoogle Play Storeでアプリリリースするのが目標になるのかもしれません。

開発環境は年々高級になっており、以前より人の思考に近い感覚コーディングできるようになってきました。

はいえ、かつてWindowsGUIプログラミングがそうであったように、

スマホにはスマホ流儀があり、いくらアイコン右クリックしたいといってもスマホには右クリック概念が無いという、

今までの常識思考の在り方に対する挑戦も数多くあります

様々な流れに翻弄されつつもプロダクトを開発し世にリリースしていくことは、

プログラマ選択できる使命の一つとして今後も世界中で支持されていくと私は信じています

プログラミングとりまく状況はこの30年で大きく変化したと言えます

それでも基本的な部分は変わりがありません……などというのが通例ですが、

からといって基礎練を素直に続けることが正しいとも思いません。

今の新しい世代の人なら、まずはスマホアプリWebアプリWebサイトを目指すべきでしょう。

ハードウェアに興味があるなら、ラズベリーパイやArdinoを組み合わせても面白いですね。

すると、今とっかかりにすべき言語も絞られてきます

アプリならJavaSwift。(Unityを使うならC#ですね)

Web系ならphp。(ruby on railsもいいかと思います)

(15年前だったらC++でかっこいいwincdowsゲームを作りたい若者で溢れていました)

何かを作るにあたり、まずは1ボタン1機能から始めると良いと思います

ボタンを押したら、何かコマンドを実行する。

それはメール送信だったり、画面に文字を表示したり、ショップではがねのつるぎを購入したりと様々です。

技量が上がると、ボタンを増やしたくなります

ボタンを押すとボタンが増えたり減ったり、違う画面に移ったりしたくなります

途端に難しくなります

それらを整理するためにオブジェクト指向とやらを使わないといけなくなります

バグを出しにくくするための工夫が必要になってきます

何かを作る際に、機能が多くなると、それらを整理する手間が発生します。

グローバル変数はやめようとか、goto禁止というのはそういう活動の一環として生み出されてきたハウツーです。

そして自分の作りたいものは往々にして自分の実力を超えた所にあります

そこで挑戦と葛藤が始まります

幾多の困難を乗り越え、今の自分ならどの程度の規模のものを無理なく作れるかということがわかる場合があります。(わからない場合の方が多いんですけど)

するとあることに気づきます

自由に作りたいものを列挙するのは重要ですが、

最終的に何を作るか、何を作れるかというものを見据えながら、本当に必要機能を選別しないといけないのです。

欲しいものは全ては手に入りません。

全部じゃないと意味が無いなら、即座に全てをあきらめるか、考え方を変えなければ生き残れません。

プログラミングをする上で、夢を実現する技術を学ぶわけですが、

それには、何を実現したいと願うか、何を夢とするか、をコントロールする術も含まれます

そしてそれこそが、プログラミング、ひいては

生きていくために大切な希望を見つけるための技術であると気づかされます

アーカイブ ヘルプ
ログイン ユーザー登録
ようこそ ゲスト さん