不可解なretrun文

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
オカピーα
記事: 120
登録日時: 13年前

不可解なretrun文

#1

投稿記事 by オカピーα » 12年前

Win32APIを学んでそれなりに経つのに
いまだにC言語の初歩の「return」文が理解できていないために
不具合が発生。
したのコードを見てください。


main.cpp

コード:

/*Lunaスタイルの適応*/
#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
/*WindowsXPへの適応*/
#define _WIN32_WINNT 0x0501
/*ヘッダファイルのインクルード*/
#include <windows.h>
#include "resource.h"
#include <commctrl.h>
#include "header.h"
#include <windowsx.h>
/*Libファイルのリンク*/
#pragma comment(lib, "comctl32.lib")      // ツリービューの作成に必要



/*リテラル定義*/
#define SPLIT_WIDTH 2
#define SPLIT_MIN 50
#define MAXTAB 10
/*グローバル変数*/
HINSTANCE hInst;                          // 現在のインターフェイス
int width = 150;                         // 分割ウインドウ(左)の幅
/*ウィンドウハンドル*/
HWND hWnd;
HWND hTree;
HWND hEdit;
HWND hCombo1;                             // コンボボックスのハンドル
HWND hToolBar;                            // ツールバーのウィンドウハンドル
HWND hRebar;							 // レバーコントロールのハンドル
HWND hStatus;
HWND hTab;            // タブコントロールのハンドル
WNDPROC defProc;

//エディット入力内容
TCHAR szEditBuf[MAXTAB][1024*1024];

// TBBUTTON(ツールバーボタン)型の配列
TBBUTTON tbButton[] = {
  { STD_FILEOPEN, ID_BUTTON1, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0},
  { STD_FILESAVE, ID_BUTTON2, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0},
  { STD_COPY,     ID_BUTTON3, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0},
  { STD_CUT,      ID_BUTTON4, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0},
  { STD_DELETE,   ID_BUTTON5, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0},
  { STD_PASTE,    ID_BUTTON6, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0},
  { STD_REDOW,    ID_BUTTON7, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0},
  { STD_UNDO,     ID_BUTTON8, TBSTATE_ENABLED, TBSTYLE_BUTTON | BTNS_AUTOSIZE, 0, 0, 0}
};
TBBUTTON tbSPACE = {0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0, 0L};

/* コールバック関数/初期化関数 */
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ToolbarProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

/* 関数の定義 */

void AddItemTree();

int OpenFile();
int NewFile();
int SaveAsFile();
int SaveFile();
int ConfirmFile();


TCHAR szTitle[128] = TEXT("test");
TCHAR szTitle_org[] = TEXT("test [ %s ]");
TCHAR szFile[MAX_PATH];
TCHAR szFileTitle[MAX_PATH];
TCHAR szFileNameList[MAXTAB][MAX_PATH] = {0};


TCITEM AddTi;


int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine,
                     int nCmdShow)
{
    MSG msg;
    MyRegisterClass(hInstance);
    HACCEL hAccel;
    BOOL bRet;

    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }
	
	// アクセラレータテーブルを読み込む
	hAccel = LoadAccelerators( hInst, TEXT("ACCEL") );

	// メッセージループ
	while((bRet = GetMessage(&msg,NULL,0,0)) != 0){
		if(bRet == -1){
			break;
		}else{
			if(!TranslateAccelerator(hWnd,hAccel,&msg)){
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
	}
	return (int)msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX 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(hInst ,MAKEINTRESOURCE(TEST_ICON));
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MENU);
    wcex.lpszClassName = TEXT("test");
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(TEST_ICON));

    return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{


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

   hWnd = CreateWindow(TEXT("test"),TEXT("test Ver.1.0.1.1") , WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    static BOOL push = FALSE;
    RECT Rect;                // RECT構造体
	static RECT winRect,staRect;
    INITCOMMONCONTROLSEX ic;  // INITCOMMONCONTROLSEX構造体
    REBARBANDINFO rbBand;     // REBARBANDINFO構造体
    HFONT hFont;              // フォント
    LPCTSTR szBuf_edit1;
    LPCTSTR strItem1[] = {
      TEXT("COM1") ,
      TEXT("COM2") ,
      TEXT("COM3")
    };
    UINT i;
    UINT index;
    UINT com_no;
    TBADDBITMAP tb;
    int nTab;
    static RECT Tabrc;
    //TCITEM ti;
    //LPMINMAXINFO lpmm;
	static HFONT hEditFont;
	RECT ReSize;

    switch (msg)
    {
        case WM_CREATE:
			InitCommonControls();			//コモンコントロール初期化処理

            hTree = CreateWindowEx(WS_EX_CLIENTEDGE, // 拡張ウィンドウスタイル
                WC_TREEVIEW,
                TEXT(""),
                WS_CHILD | WS_BORDER | WS_VISIBLE | TVS_HASLINES |
                TVS_HASBUTTONS | TVS_LINESATROOT | TVS_CHECKBOXES | TVS_EDITLABELS | TVS_NONEVENHEIGHT | TVS_NOSCROLL
				,
                0, 0,
                0, 0,
                hWnd,
                (HMENU)IDC_TREE,
                hInst,
                NULL);
            hTab = CreateWindowEx(0,
                WC_TABCONTROL, TEXT(""), 
                WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 
                0, 0, 0, 0, 
                hWnd, (HMENU)ID_TAB, hInst, NULL);
            hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, // 拡張ウィンドウスタイル
                TEXT("EDIT"),
                TEXT(""),
                WS_CHILD | WS_VISIBLE | ES_WANTRETURN | ES_MULTILINE | 
				ES_AUTOVSCROLL | WS_VSCROLL | ES_AUTOHSCROLL | WS_HSCROLL,
                0, 0,
                0, 0,
                hTab,
                (HMENU)IDC_EDIT2,
                hInst,
                NULL);
			Edit_LimitText(hEdit,0);
			AddItemTree();		//ツリービューに要素を挿入


            //コモンコントロールの初期化  
            ic.dwICC = ICC_COOL_CLASSES | ICC_BAR_CLASSES;
            ic.dwSize = sizeof(INITCOMMONCONTROLSEX); 
            InitCommonControlsEx(&ic); 

            //レバーコントロールの作成
            hRebar = CreateWindowEx(0,REBARCLASSNAME,TEXT(""),
                      WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS |WS_CLIPCHILDREN | CCS_NODIVIDER,
                      0, 0, 0, 0,
                      hWnd, (HMENU)ID_COOL,
                      (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);

            // REBARBANDINFO構造体
            ZeroMemory(&rbBand, sizeof(REBARBANDINFO)); 
            // 構造体のサイズ
            rbBand.cbSize = sizeof(REBARBANDINFO);
            // マスクフラグ
            rbBand.fMask = RBBIM_STYLE | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_BACKGROUND;
            // バンドの背景
            rbBand.hbmBack = LoadBitmap((HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
                              MAKEINTRESOURCE(IDB_BITMAP1));
            // バンドのスタイルフラグ
            rbBand.fStyle = RBBS_CHILDEDGE;   
            // 最小値の高さ
            rbBand.cyMinChild = 21;
            // 最小値の幅
            rbBand.cxMinChild = 100;
            // レバーコントロールにのせる対象の子ウインドウのハンドル
            hFont = CreateFont(12, 0, 0, 0,
                      FW_NORMAL, FALSE, FALSE, FALSE,
                      SHIFTJIS_CHARSET,
                      OUT_DEFAULT_PRECIS,
                      CLIP_DEFAULT_PRECIS,
                      DEFAULT_QUALITY,
                      FF_MODERN,
                      TEXT("MS Pゴシック"));
            hCombo1 = CreateWindowEx(0, TEXT("COMBOBOX"), TEXT(""),
                       WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,
                       0, 0, 0, 0,
                       hRebar, (HMENU)ID_COMBO1, 
                       (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE) ,NULL);
            SendMessage(hCombo1, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(true, 0));
            // コンボボックスにデータを詰めていく
            for (i = 0 ; i < 3 ; i++)
            {
                SendMessage(hCombo1 , CB_ADDSTRING , 0 , (LPARAM)strItem1[i]);
            }
            // ウインドウ生成時にはじめに表示するデータを指定
            index = SendMessage(hCombo1, CB_FINDSTRINGEXACT, -1, (LPARAM)TEXT("COM1"));
            SendMessage(hCombo1, CB_SETCURSEL, index, 0);
            rbBand.hwndChild = hCombo1;

            // レバーコントロールにコンボボックス1を挿入 
            SendMessage(hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);

            // レバーコントロールにツールバーを挿入
            hToolBar = CreateWindowEx(
                0,                //拡張スタイルなし
                TOOLBARCLASSNAME, // クラスネーム
                NULL,             //ウィンドウタイトル
                WS_CHILD
                 | WS_VISIBLE
                 | CCS_NODIVIDER
                 | CCS_NORESIZE
                 | TBSTYLE_FLAT,  //ウィンドウスタイル
                0, 0,             //ウィンドウ位置
                0, 0,             //ウィンドウ幅、高さ
                hRebar,           //親ウィンドウ
                (HMENU)IDW_TOOL,  //コントロール識別子
                (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE) ,   //インスタンスハンドル
                NULL);            //pointer to window-creation data 
            tb.hInst = HINST_COMMCTRL;    // ボタンをシステム定義のビットマップ
            tb.nID = IDB_STD_SMALL_COLOR; // システム標準ビットマップ(小)
            SendMessage(hToolBar, TB_ADDBITMAP, 0, (LPARAM)&tb); 

            /* TBBUTTON 構造体のサイズを設定 */
            SendMessage(hToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
            /* ツールバーにボタンを挿入 */
            SendMessage(hToolBar, TB_ADDBUTTONS, (WPARAM)8, (LPARAM)(LPTBBUTTON)&tbButton);
            // ボタンの区切りを挿入
            SendMessage(hToolBar, TB_INSERTBUTTON, 2, (LPARAM)&tbSPACE);
            /* ツールバーサブクラス化 */
            defProc = (WNDPROC)GetWindowLong(hToolBar, GWL_WNDPROC);
            SetWindowLong(hToolBar, GWL_WNDPROC, (LONG)ToolbarProc);
            SetWindowLong(hToolBar, GWL_USERDATA, (LONG)defProc);

            rbBand.hwndChild = hToolBar;
            GetClientRect(hRebar, &Rect);
            rbBand.cx = Rect.right - 100;
            SendMessage(hRebar, RB_INSERTBAND, (WPARAM)-1, (LPARAM)&rbBand);

			GetWindowRect(hRebar,&winRect);
			GetWindowRect(hStatus,&staRect);

            GetClientRect(hWnd, &Tabrc);
			// ステータスバーを作成
			hStatus = CreateStatusWindow(
				WS_CHILD | WS_VISIBLE | CCS_BOTTOM | SBARS_SIZEGRIP,
				"",
				hWnd,
				ID_STATUS
			);
			SendMessage(hTab, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), 0);

			SendMessage(hTree,TVM_SETITEMHEIGHT,(WPARAM)16,0);

			hEditFont = CreateFont(15, 0, 0, 0, /* フォントの高さ,平均文字幅,文字送り方向の角度,ベースラインの角度 */
			FW_NORMAL, FALSE, FALSE, 0, /* フォントの太さ,斜体,下線,取り消し線 */
			SHIFTJIS_CHARSET, /* 文字セットの識別子 */
			OUT_DEFAULT_PRECIS, /* 出力精度 */
			CLIP_DEFAULT_PRECIS, /* クリッピング精度 */
			DEFAULT_QUALITY, DEFAULT_PITCH, "MS Pゴシック"); /* 出力品質,ピッチとファミリ,フォント名 */

			SendMessage(hEdit, WM_SETFONT, (WPARAM)hEditFont, MAKELPARAM(FALSE, 0)); /* フォントの変更 */
			NewFile();
			SetFocus(hEdit);

			break;
		case WM_NOTIFY:
			//ツリービューの通知メッセージ処理
			if (((LPNMHDR)lParam)->code == TVN_SELCHANGED) {
				TCHAR    szBuf[256];
				TVITEMEX item;

				item.mask       = TVIF_HANDLE | TVIF_TEXT;
				item.hItem      = ((LPNMTREEVIEW)lParam)->itemNew.hItem;
				item.pszText    = szBuf;
				item.cchTextMax = sizeof(szBuf) / sizeof(TCHAR);
				TreeView_GetItem(hTree, &item);
				GetWindowRect(hWnd,&ReSize);

		MessageBox(NULL, szBuf, TEXT("OK"), MB_OK);
	}
			//タブコントロールの通知メッセージ処理
			switch (((NMHDR *)lParam)->code) {
                case TCN_SELCHANGE:
                    nTab = TabCtrl_GetCurSel(hTab);
					SetWindowText(hEdit, szEditBuf[nTab]);

                    break;
                case TCN_SELCHANGING:
                    nTab = TabCtrl_GetCurSel(hTab);
					GetWindowText(hEdit, szEditBuf[nTab], sizeof(szEditBuf[nTab]));
                    break;
            }
			break;
        case WM_SIZE:
			MoveWindow(hTree, 0, winRect.bottom - winRect.top, width - SPLIT_WIDTH, HIWORD(lParam) - (winRect.bottom - winRect.top) - 25, TRUE);
            MoveWindow(hEdit, width + SPLIT_WIDTH-148  , winRect.bottom - winRect.top , LOWORD(lParam)-160, HIWORD(lParam) - 80 , TRUE);
			MoveWindow(hTab, width + SPLIT_WIDTH, winRect.bottom - winRect.top, LOWORD(lParam), HIWORD(lParam)- (winRect.bottom - winRect.top) - 25, TRUE);
            SendMessage(hRebar, WM_SIZE, wParam, lParam);
			SendMessage(hStatus, WM_SIZE, wParam, lParam );
            break;

        case WM_COMMAND:
            wmId = LOWORD(wParam);
            wmEvent = HIWORD(wParam);
            switch (wmId)
            {
                case ID_COMBO1:
                    if (HIWORD(wParam) == CBN_SELCHANGE)
                    { 
                        // 現在のコンボボックスのデータを取得
                        com_no = (UINT)SendMessage(hCombo1, CB_GETCURSEL, 0, 0);
                        // テキストの表示
                        szBuf_edit1 = strItem1[com_no];
                        MessageBox(hWnd, szBuf_edit1, TEXT("メッセージ"), MB_OK);
                    }
                    break;
                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;
				case IDM_OPEN:
					OpenFile();
					break;
				case IDM_NEW:
					NewFile();
					break;
				case IDM_SAVEAS:
					SaveAsFile();
					break;
				case IDM_SAVE:
					SaveFile();
					break;

                default:
                    return DefWindowProc(hWnd, msg, wParam, lParam);
            }
            break;
		case WM_CLOSE:
			if (ConfirmFile() == IDCANCEL)
				return -1;
			DeleteObject(hEditFont);
			DestroyWindow(hWnd);
			break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hWnd, msg, wParam, lParam);
    }
    return 0;
}


void AddItemTree(){

    HTREEITEM hParent1, hParent2, hParent3, hChild1, hChild2;
    TV_INSERTSTRUCT tv;

            tv.hInsertAfter = TVI_LAST;
            tv.item.mask = TVIF_TEXT;
            tv.hParent = TVI_ROOT;
            tv.item.pszText = TEXT("親1");
            hParent1 = TreeView_InsertItem(hTree, &tv);

            tv.item.pszText = TEXT("親2");
            hParent2 = TreeView_InsertItem(hTree, &tv);

            tv.item.pszText = TEXT("親3");
            hParent3 = TreeView_InsertItem(hTree, &tv);

            tv.hParent = hParent1;
            tv.item.pszText = TEXT("子1");
            hChild1 = TreeView_InsertItem(hTree, &tv);
            tv.item.pszText = TEXT("子2");
            hChild2 = TreeView_InsertItem(hTree, &tv);
            tv.hParent = hChild1;
            tv.item.pszText = TEXT("孫1");
            TreeView_InsertItem(hTree, &tv);
            tv.hParent = hChild1;
            tv.item.pszText = TEXT("孫2");
            TreeView_InsertItem(hTree, &tv);
            tv.hParent = hParent2;
            tv.item.pszText = TEXT("子3");
            TreeView_InsertItem(hTree, &tv);
            tv.hParent = hParent3;
            tv.item.pszText = TEXT("子4");
            TreeView_InsertItem(hTree, &tv);
}

//* ツールバーサブクラス */
//* WindowsXPにおいて、
//ツールバーのボタン上でマウスの左ボタンを押したまま右ボタンを押すと、
//それ以降のマウス操作を正常に受け付けなくなる。 */
LRESULT CALLBACK ToolbarProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_RBUTTONDOWN:
        case WM_RBUTTONUP:
            if (SendMessage(hWnd, TB_GETHOTITEM, 0, 0) >= 0){
                ReleaseCapture();
            }
            return 0;
    }
    return CallWindowProc(defProc, hWnd, msg, wParam, lParam);
}





int OpenFile()
{
    int id;
    HWND hMain;
    DWORD dwSize = 0L;
    OPENFILENAME ofn;
    HANDLE hFile;
    DWORD dwAccBytes;
    LPTSTR lpszBuf;

    HGLOBAL hMem;

    id = ConfirmFile();
    if (id == IDCANCEL)
        return -1;

    // OPENFILENAME構造体を設定
    memset(&ofn, 0, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = hEdit;
    ofn.lpstrFilter =
        TEXT("テキストファイル(*.txt)\0*.txt\0すべてのファイル(*.*)\0*.*\0\0");
    ofn.lpstrFile = szFile;
    ofn.lpstrFileTitle = szFileTitle;
    ofn.nMaxFile = MAX_PATH;
    ofn.nMaxFileTitle = MAX_PATH;
    ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
    ofn.lpstrDefExt = TEXT("txt");
    ofn.lpstrTitle = TEXT("ファイルを開く");

    if(GetOpenFileName(&ofn) == 0)  // 「ファイルを開く」ダイアログ
        return -1;

    hFile = CreateFile(szFile,  // ファイル名
        GENERIC_READ,           // 読み取り/書き込みアクセス
        0,                      // 共有設定 0だと共有対象としない
        NULL,                   // セキュリティ属性
        OPEN_ALWAYS,            // ファイルがすでに存在しているかどうか
        FILE_ATTRIBUTE_NORMAL,  // ファイル属性
        NULL);
    dwSize = GetFileSize(hFile, NULL);  // ファイルサイズを取得

    // メモリを動的に確保
    hMem = GlobalAlloc(GHND, dwSize + sizeof(TCHAR));
    if (hMem == NULL) {
        MessageBox(hEdit, TEXT("メモリの確保に失敗しました\nメモリの残量を確認してください"),
                   TEXT("test"),
				   MB_ICONERROR | MB_OK);
        return -1;
    }
    lpszBuf = (LPTSTR)GlobalLock(hMem);

    // ファイルを読み込み、エディットコントロールに表示する
    ReadFile(hFile, lpszBuf, dwSize, &dwAccBytes, NULL);
    lpszBuf[dwAccBytes] = TEXT('\0');

	AddTi.mask = TCIF_TEXT;
    AddTi.pszText = szFile;
	int nTab = TabCtrl_GetRowCount(hTab);
	TabCtrl_InsertItem(hTab,nTab + 1, &AddTi);
	InvalidateRect(hTab,NULL,TRUE);
	TabCtrl_SetCurSel(hTab,nTab + 1);

    Edit_SetText(hEdit, lpszBuf);

    CloseHandle(hFile);
    GlobalUnlock(hMem);
    GlobalFree(hMem);

    return 0;
}

int SaveAsFile()
{
    OPENFILENAME ofn;
    HANDLE hFile;
    DWORD dwAccBytes;
	TCITEM GetTi;
    LPTSTR lpszBuf;
    int nLen;
    HGLOBAL hMem;

	int nTab = TabCtrl_GetCurSel(hTab);
    // エディットコントロールに書き込まれている文字数を取得し、
    // それに見合うメモリを動的に確保
    nLen = GetWindowTextLength(hEdit);
    hMem = GlobalAlloc(GHND, sizeof(TCHAR) * (nLen + 1));
    lpszBuf = (LPTSTR)GlobalLock(hMem);

    // エディットコントロールの内容をlpszBufに保管
    GetWindowText(hEdit, lpszBuf, nLen + 1);

    // OPENFILENAME構造体を設定
    memset(&ofn, 0, sizeof(OPENFILENAME));
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = hEdit;
    ofn.lpstrFilter =
        TEXT("テキストファイル(*.txt)\0*.txt\0すべてのファイル(*.*)\0*.*\0\0");
    ofn.lpstrFile = szFile;
    ofn.lpstrFileTitle = szFileTitle;
    ofn.nFilterIndex = 1;
    ofn.nMaxFile = MAX_PATH;
    ofn.nMaxFileTitle = MAX_PATH;
    ofn.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
    ofn.lpstrDefExt = TEXT("txt");
    ofn.lpstrTitle = TEXT("名前を付けて保存する");

    if(GetSaveFileName(&ofn) == 0)  // 「ファイルを保存」ダイアログ
        return -1;

	//ファイルの絶対パスを格納
	lstrcpy(szFileNameList[nTab],szFile);

    // ファイルにlpszBufの内容を書き込む
    hFile = CreateFile(szFileNameList[nTab], GENERIC_WRITE, 0, NULL,
                CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(hFile, lpszBuf, (DWORD)lstrlen(lpszBuf),
              &dwAccBytes, NULL);

	AddTi.mask = TCIF_TEXT;
    AddTi.pszText = szFile;
    //TabCtrl_InsertItem(hTab, 0, &AddTi);
	//nTab = TabCtrl_GetCurSel(hTab);
	TabCtrl_SetItem(hTab,nTab,&AddTi);
	TabCtrl_SetCurSel(hTab,nTab);
	InvalidateRect(hTab,NULL,TRUE);

    if(CloseHandle(hFile) == 0)
        MessageBox(hEdit, TEXT("ハンドルのクローズに失敗しました\nユーザーの操作に欠陥はありません"),
                   TEXT("test"), MB_OK);

    // エディットコントロールの変更フラグをFALSEに設定
    SendMessage(hEdit, EM_SETMODIFY, FALSE, 0);

    GlobalUnlock(hMem);
    GlobalFree(hMem);

    return 0;
}

int SaveFile()
{
    HANDLE hFile;
    DWORD dwAccBytes;
    int nLen;
    LPTSTR lpszBuf;
    HGLOBAL hMem;


	int nTab = TabCtrl_GetCurSel(hTab);

    if (lstrcmp(szFileNameList[nTab], TEXT("") ) == 0) {
        SaveAsFile();
        return -1;
    }
	
	// エディットコントロールに書き込まれている文字数を取得し、
    // それに見合うメモリを動的に確保
    nLen = GetWindowTextLength(hEdit);
    hMem = GlobalAlloc(GHND, nLen + sizeof(TCHAR));
    lpszBuf = (LPTSTR)GlobalLock(hMem);

    // エディットコントロールの内容をlpszBufに保管
    GetWindowText(hEdit, lpszBuf, nLen + 1);

    // ファイルにlpszBufの内容を書き込む
	hFile = CreateFile(szFileNameList[nTab], GENERIC_WRITE, 0, NULL,
                TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(hFile, lpszBuf, (DWORD)lstrlen(lpszBuf),
              &dwAccBytes, NULL);

    GlobalUnlock(hMem);
    GlobalFree(hMem);

    // エディットコントロールの変更フラグをFALSEに設定
    SendMessage(hEdit, EM_SETMODIFY, FALSE, 0);

    if (CloseHandle(hFile) == 0) {
        MessageBox(hEdit, TEXT("ハンドルのクローズに失敗しました\nユーザーの操作に欠陥はありません"),
                   TEXT("test"), MB_OK | MB_ICONERROR);
        return -1;
    }

    return 0;
}

int ConfirmFile()
{
    int id;

    if (SendMessage(hEdit, EM_GETMODIFY, 0, 0) == TRUE) {
        id = MessageBox(hEdit,
            TEXT("文書が更新されています。\n変更を保存しますか?"),
            TEXT("test"),
            MB_YESNOCANCEL | MB_ICONEXCLAMATION);
        if (id == IDYES) {
            SaveFile();
        } else if (id == IDCANCEL) {
            return IDCANCEL;
        } else if (id ==  IDNO) {
            return IDNO;
        }
    }
    return 0;
}

int NewFile()
{
    int id;
	int nTab;

    id = ConfirmFile();
    if (id == IDCANCEL) {
        return -1;
    }

    
	AddTi.mask = TCIF_TEXT;
    AddTi.pszText = TEXT("無題");
	nTab = TabCtrl_GetCurSel(hTab);
    TabCtrl_InsertItem(hTab, nTab + 1 , &AddTi);
	TabCtrl_SetCurSel(hTab,nTab +1 );
    Edit_SetText(hEdit, TEXT(""));
	
	InvalidateRect(hTab,NULL,TRUE);
	
    lstrcpy(szFileNameList[nTab + 1], TEXT(""));
    return 0;
}

header.h

コード:

#define IDC_TREE 1001
#define IDC_EDIT2 1002
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDC_HP 109
#define IDW_TOOL 149
#define ID_COOL 150
#define ID_COMBO1 165
#define ID_COMBO2 166
#define IDC_COMBO1 161
#define IDC_COMBO2 162
#define ID_BUTTON1 151
#define ID_BUTTON2 152
#define ID_BUTTON3 153
#define ID_BUTTON4 154
#define ID_BUTTON5 155
#define ID_BUTTON6 156
#define ID_BUTTON7 157
#define ID_BUTTON8 158
#define ID_STATUS 2005
#define ID_TAB 1008
#define IDC_RICHEDIT 158
resource.h

コード:

#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#define IDM_ABOUT                               104
#define IDM_EXIT                                105
#define IDC_MENU                                110
#define IDB_BITMAP1                             111
#define TEST_ICON                          123
//#define IDR_ACCELERATOR                         127
#define IDM_OPEN                                40000
#define IDM_NEW                                 40001
#define IDM_SAVEAS                              40002
#define IDM_SAVE                                40003
main.rc

コード:

// Generated by ResEdit 1.5.9
// Copyright (C) 2006-2011
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"




//
// Bitmap resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDB_BITMAP1        BITMAP         ".\\reber.bmp"



//
// Menu resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDC_MENU MENU
BEGIN
    POPUP "ファイル(&F)"
    BEGIN
        MENUITEM "新規作成(&N)\tCtrl + N", IDM_NEW
        MENUITEM "ファイルを開く(&O)...\tCtrl + O", IDM_OPEN
        MENUITEM "上書き保存(&S)\tCrtl + S", IDM_SAVE
        MENUITEM "名前を付けて保存(&A)...\tCtrl + A", IDM_SAVEAS
        MENUITEM SEPARATOR
        MENUITEM "アプリケーションの終了(&X)\tCtrl + Q", IDM_EXIT
    END
    POPUP "ヘルプ(&H)"
    BEGIN
        MENUITEM "バージョン情報(&A)...", IDM_ABOUT
    END
END



//
// Accelerator resources
//
ACCEL ACCELERATORS
BEGIN
    "O",            IDM_OPEN, VIRTKEY, CONTROL ,NOINVERT
    "N",            IDM_NEW, VIRTKEY, CONTROL ,NOINVERT
    "S",            IDM_SAVE, VIRTKEY, CONTROL ,NOINVERT
    "A",            IDM_SAVEAS, VIRTKEY, CONTROL ,NOINVERT
    "Q",            IDM_EXIT, VIRTKEY, CONTROL ,NOINVERT
END



//
// Icon resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
TEST_ICON     ICON           ".\\test.ico"

不具合を説明します。

1.起動(異常なし)
2.エディットに何らかの文字を入力(異常なし)
3.閉じる(異常なし)
4.保存の有無を聞かれるので「はい」(異常なし)
5.名前をつけて保存ダイアログ表示(異常なし)
6.「キャンセル」(異常あり)

6を実行するとウィンドウが異常消滅します。
おそらくreturnが異常な数字を返しているせいだと思うのですが
さてどうしたらいいのかわかりません。
そもそもなんでここでreturnするのかもよくわかりません。
returnで返した「-1」はいったいどこに行くのでしょう?

解決法とreturn文を解説してください。
お願いします!


http://dixq.net/forum/viewtopic.php?f=3&t=11673
は自力で解決できてしまったので削除させていただきます。
softya(ソフト屋)さんありがとうございました。
C,C++,C#,これらを極めることを「3C政策」と言う

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 不可解なretrun文

#2

投稿記事 by softya(ソフト屋) » 12年前

これは、どこのreturnの話でしょうか?
return -1が何処の話か絞り込めると無駄なソースコード解析や調査をしなくて良いのですが。

【補足】
ウィンドウプロシージャの戻り値の話しであれば、ウィンドウメッセージによって意味が変わるとしか答えられません。
WM_CLOSEの時に-1を返した場合は未定義かと思います。
http://msdn.microsoft.com/en-us/library ... 85%29.aspx
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

box
記事: 2002
登録日時: 14年前

Re: 不可解なretrun文

#3

投稿記事 by box » 12年前

戻り値の型がintで、確かにその関数からint型の値を返しているのですが、
返ってきたはずの戻り値を使っていない箇所があるようです。
意図的にそのようになさっていますか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: 不可解なretrun文

#4

投稿記事 by へにっくす » 12年前

ざっとみただけですが、
WM_CLOSEでの戻り値が間違っていると思われます。

コード:

        case WM_CLOSE:
            if (ConfirmFile() == IDCANCEL)
                return -1;
            DeleteObject(hEditFont);
            DestroyWindow(hWnd);
            break;
以下のサンプルを見る限りでは、returnで戻してるのは0固定ですよ。
ウィンドウを閉じる(Windows)

以下のリンクの説明でも、
WM_CLOSE Message

コード:

Return value
Type: LRESULT
If an application processes this message, it should return zero.
戻す値は0にしてください
と読めますよね。
written by へにっくす

閉鎖

“C言語何でも質問掲示板” へ戻る