Win32APIにおける、MDIWindow形成について

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

Win32APIにおける、MDIWindow形成について

#1

投稿記事 by ひぐらし » 11年前

Win32APIをVisual Studio2010、Windows 7の環境下でプログラムを書いています。
今までうまく進んでいたのですが、今日突然
~.exe の 0x756e76f1 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000000 を読み込み中にアクセス違反が発生しました。
というエラーを吐き出してきました。突然のことだったのと、初心者なので直し方がわかりません。
助言を頂けると助かります。
様々なプログラムのところから、ここを取り出しているので乗ってない変数などはありますが そこまで進むことなくエラーを吐き出しているため、今回は載せていません。

win.cpp

コード:

#include "complex.h"
#include "file.h"
#include "win.h"

data dat;

int f_flag;
HWND g_hWnd;
LPVOID lpMsgBuf;

Win::Win(void) {
};
Win::Win(HINSTANCE thInst) {
	this->inf.hInst=thInst;
};
Win_infor Win::ShowInf(void) {
	return this->inf;
};

ATOM Win::InitWin(BOOL flag) {
	inf.wc.cbSize=sizeof(WNDCLASSEX),inf.wc.hInstance=this->inf.hInst;
	inf.wc.hIcon=LoadIcon(NULL,IDI_APPLICATION),inf.wc.hIconSm=LoadIcon(NULL,IDI_WINLOGO);
	inf.wc.hCursor=LoadCursor(NULL,IDC_ARROW);
	if(flag) {
		inf.wc.style=0,inf.wc.lpfnWndProc=WinProc;
		inf.wc.cbClsExtra=inf.wc.cbWndExtra=0;
		inf.wc.hbrBackground=(HBRUSH)(COLOR_APPWORKSPACE+1);
		inf.wc.lpszClassName=TEXT("frame"),inf.wc.lpszMenuName=TEXT("M_MENU");
	} else {
		inf.wc.style=CS_HREDRAW|CS_VREDRAW,inf.wc.lpfnWndProc=C_WinProc;
		inf.wc.cbClsExtra=0,inf.wc.cbWndExtra=sizeof(WORD);
		inf.wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
		inf.wc.lpszClassName=TEXT("child"),inf.wc.lpszMenuName=NULL;
	}
	return RegisterClassEx(&inf.wc);
};
HWND Win::CreateFWin(int nCmdShow) {
ここでエラーを吐き出します⇒ inf.hWnd=CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("frame"),TEXT("N20mFringe"),WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,100,100,500,500,HWND_DESKTOP,NULL,this->inf.hInst,NULL); 
	if(!inf.hWnd) return false;
	else {
		ShowWindow(inf.hWnd,nCmdShow);
		UpdateWindow(inf.hWnd);

		return inf.hWnd;
	}
};

C_Win::C_Win(void) {
};
HWND C_Win::CreateCWin(HWND FhWnd,HWND CLhWnd,RECT rect,LPCTSTR szTitle) {
	mdics.szClass=TEXT("child"),mdics.szTitle=szTitle,mdics.hOwner=(HINSTANCE)GetWindowLongPtr(FhWnd,GWLP_HINSTANCE);
	if(szTitle==child1) {
		mdics.x=mdics.y=0,mdics.cx=rect.right,mdics.cy=rect.bottom/2;
		mdics.style=WS_OVERLAPPED|WS_HSCROLL|WS_CAPTION|WS_VISIBLE;
	}
	if(szTitle==child2) {
		mdics.x=0,mdics.y=rect.bottom/2,mdics.cx=rect.right,mdics.cy=rect.bottom;
		mdics.style=WS_OVERLAPPED|WS_CAPTION|WS_VISIBLE;
	}
	mdics.lParam=0;
	hWnd=(HWND)SendMessage(CLhWnd,WM_MDICREATE,0,(LPARAM)(LPMDICREATESTRUCT)&mdics);
	if(szTitle==child1) SetWindowWord(hWnd,0,1);
	if(szTitle==child2) SetWindowWord(hWnd,0,2);

	return hWnd;
};

LRESULT CALLBACK WinProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) {
	C_Win C_Win1,C_Win2;
	File File;

	HINSTANCE hInst=(HINSTANCE)GetWindowLongPtr(hWnd,GWLP_HINSTANCE);
	RECT rect;

	static HWND CLhWnd,ChWnd1,ChWnd2;
	switch(msg) {
	case WM_CREATE:
		GetClientRect(hWnd,&rect);
		SetLastError(NO_ERROR);
		Frame WindowのMenuNameをNULLにすると、ここまで進んでエラーになります ⇒ CLhWnd=CreateWindow(TEXT("MDICLIENT"),NULL,WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN,0,0,0,0,hWnd,NULL,hInst,NULL);
		if(!CLhWnd) {
			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)&lpMsgBuf,0,NULL);
			MessageBox(NULL, (LPCWSTR)lpMsgBuf, NULL, MB_OK);
				
			LocalFree(lpMsgBuf);
			return false;
		}
		SetLastError(NO_ERROR);
		ChWnd1=C_Win1.CreateCWin(hWnd,CLhWnd,rect,child1),ChWnd2=C_Win2.CreateCWin(hWnd,CLhWnd,rect,child2);
		if(!(ChWnd1&&ChWnd2)) {
			FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)&lpMsgBuf,0,NULL);
			MessageBox(NULL, (LPCWSTR)lpMsgBuf, NULL, MB_OK);
				
			LocalFree(lpMsgBuf);
			return false;
		}

		break;
	case WM_COMMAND:
		switch(LOWORD(wp)) {
		case IDM_OPEN:
			g_hWnd=hWnd;
			DialogBox(hInst,TEXT("M_DLG"),hWnd,(DLGPROC)DlgProc);
			break;
		case IDM_CLOSE:
			SendMessage(hWnd,WM_CLOSE,0,0);
			break;
		case IDM_ANALYSIS:
			/*SendMessage(ChWnd1,WM_COMMAND,IDM_PAINT,0);
			SendMessage(ChWnd2,WM_COMMAND,IDM_PAINT,0);*/
			break;
		case IDM_FILEOPEN:
			dat=File.ReadFile(hWnd,File.FileOpen(hWnd),f_flag);
			SendMessage(ChWnd1,WM_COMMAND,IDM_PAINT,0);
			SendMessage(ChWnd2,WM_COMMAND,IDM_PAINT,0);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefFrameProc(hWnd,CLhWnd,msg,wp,lp);
	}

	return 0;
}
LRESULT CALLBACK C_WinProc(HWND hWnd,UINT msg,WPARAM wp,LPARAM lp) {
	RECT rect;
	GetClientRect(hWnd,&rect);
	PAINTSTRUCT ps;
	int w=(int)GetWindowWord(hWnd,0);
	
	switch(msg) {
	case WM_CREATE:
		break;
	case WM_PAINT:
		BeginPaint(hWnd,&ps);
		switch(w) {
		case 1:
			axis(ps.hdc,rect);
			MoveToEx(ps.hdc,10,(int)dat.P[0],NULL);
			for(int i=1;i<dat.N;i++) {
				LineTo(ps.hdc,10+i,dat.P[i]);
			}
			break;
		case 2:
			axis(ps.hdc,rect);
			break;
		}
		EndPaint(hWnd,&ps);
		ValidateRgn(hWnd,NULL);
		break;
	case WM_COMMAND:
		switch(LOWORD(wp)) {
		case IDM_PAINT:
			InvalidateRgn(hWnd,NULL,TRUE);
			break;
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefMDIChildProc(hWnd,msg,wp,lp);
	}

	return 0;
}

void axis(HDC hdc,RECT rect) {
	MoveToEx(hdc,10,10,NULL);
	LineTo(hdc,10,rect.bottom-10);
	LineTo(hdc,rect.right-10,rect.bottom-10);
}

BOOL CALLBACK DlgProc(HWND hWndDlg,UINT msg,WPARAM wp,LPARAM lp) {
	BOOL check1,check2,check3,check4;
	switch(msg) {
	case WM_INITDIALOG:
		return true;
	case WM_COMMAND:
		switch(LOWORD(wp)) {
		case ID_OPEN:
			check1=SendMessage(GetDlgItem(hWndDlg,ID_CHECK1),BM_GETCHECK,0,0);
			check2=SendMessage(GetDlgItem(hWndDlg,ID_CHECK2),BM_GETCHECK,0,0);
			check3=SendMessage(GetDlgItem(hWndDlg,ID_CHECK3),BM_GETCHECK,0,0);
			check4=SendMessage(GetDlgItem(hWndDlg,ID_CHECK4),BM_GETCHECK,0,0);

			if(check1) f_flag=0;
			else if(check2) f_flag=1;
			else if(check3) f_flag=2;
			else f_flag=3;
			SendMessage(g_hWnd,WM_COMMAND,IDM_FILEOPEN,0);
			return true;
		case IDCANCEL:
			EndDialog(hWndDlg,true);
			return true;
		}
		break;
	}
	return false;
}
win.h

コード:

#ifndef _WIN_H_
#define _WIN_H_

#include <Windows.h>
#include "resource.h"

#define child1 TEXT("cross power")
#define child2 TEXT("fringe")

struct Win_infor {
	HINSTANCE hInst;
	HWND hWnd;
	WNDCLASSEX wc;
};
class Win {
private:
	Win_infor inf;
public:
	Win();
	Win(HINSTANCE);
	Win_infor ShowInf();

	ATOM InitWin(BOOL);
	HWND CreateFWin(int);
};
class C_Win:public Win {
private:
	HWND hWnd;
	WNDCLASSEX wc;
	MDICREATESTRUCT mdics;
public:
	C_Win();

	HWND CreateCWin(HWND,HWND,RECT,LPCTSTR);
};

void axis(HDC,RECT);

LRESULT CALLBACK WinProc(HWND,UINT,WPARAM,LPARAM);
LRESULT CALLBACK C_WinProc(HWND,UINT,WPARAM,LPARAM);

BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM);

#endif /*_WIN_H_*/
m_source.cpp

コード:

#include "win.h"

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int nCmdShow) {
	
	Win FWin(hInst);
	LPVOID lpMsgBuf;
	SetLastError(NO_ERROR);
	FWin.InitWin(true);
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,NULL,GetLastError(),MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)&lpMsgBuf,0,NULL);
		MessageBox(NULL, (LPCWSTR)lpMsgBuf, NULL, MB_OK);		
		LocalFree(lpMsgBuf);
	FWin.CreateFWin(nCmdShow);
		
	FWin.InitWin(false);

	MSG msg;
	while(GetMessage(&msg,FWin.ShowInf().hWnd,0,0)) {
		if(msg.hwnd&&TranslateMDISysAccel(msg.hwnd,&msg)) continue;
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return (int)msg.wParam;
}

ひぐらし
記事: 5
登録日時: 11年前

Re: Win32APIにおける、MDIWindow形成について

#2

投稿記事 by ひぐらし » 11年前

すいません、resource.hを一応載せておきます

コード:

#include <Windows.h>

#define IDM_OPEN 1001
#define IDM_CLOSE 1002
#define IDM_ANALYSIS 2001
#define IDM_HELP 3001
#define IDM_FILEOPEN 4001

#define IDM_PAINT 10001

#define ID_OPEN 0x1001
#define ID_CHECK1 0x1002
#define ID_CHECK2 0x1003
#define ID_CHECK3 0x1004
#define ID_CHECK4 0x1005

taketoshi
記事: 222
登録日時: 14年前
住所: 日本国

Re: Win32APIにおける、MDIWindow形成について

#3

投稿記事 by taketoshi » 11年前

今まで動いていたのが、突然動かなくなったのでしたらソリューションとビルドのクリーンを試してみてください。

http://msdn.microsoft.com/ja-jp/library/5tdasz7h.aspx

コピペでソースを書いた場合VSが新たな記述を認識せず正常にコンパイルされていない可能性があります。

ひぐらし
記事: 5
登録日時: 11年前

Re: Win32APIにおける、MDIWindow形成について

#4

投稿記事 by ひぐらし » 11年前

taketoshi様、返信ありがとうございます。
試してみたのですが、駄目でした。
WNDCLASSEXのlpszMenuNameを変更すると、フレームウインドウが形成できるということはそこに問題があるのでしょうか?
WNDCLASSEXのところでエラーを吐き出させようとしても、正常に行われました。
とGetLastErrorが吐き出すばかりで分からず仕舞いです。

taketoshi
記事: 222
登録日時: 14年前
住所: 日本国

Re: Win32APIにおける、MDIWindow形成について

#5

投稿記事 by taketoshi » 11年前

自前で制作していたのMDIプログラムに対して、提示されたコードに改変して動かしてみました

コード:

//フレームウインドウクラス
char szFrameClassName[] = "mdi01";
char *szApplicationTitle = "Windowエディタ";
hFrame = CreateWindowEx(NULL,szFrameClassName,szApplicationTitle,WS_OVERLAPPEDWINDOW,100,100,500,500,HWND_DESKTOP,NULL,hInstance,NULL); 
このコードならばhFrameハンドルは取得され、MDIウインドウが表示されます。

コード:

hFrame = CreateWindowEx(NULL,TEXT("frame"),TEXT("N20mFringe"),WS_OVERLAPPEDWINDOW,100,100,500,500,HWND_DESKTOP,NULL,hInstance,NULL); 
このコードではhFrameはNULLで取得できませんでした。文字コードの問題だと思いますが、ウインドウクラスの指定の仕方がダメっぽいですね。

ひぐらし
記事: 5
登録日時: 11年前

Re: Win32APIにおける、MDIWindow形成について

#6

投稿記事 by ひぐらし » 11年前

返信ありがとうございます。
同じことをしてみたのですが、同様のエラーが得られました。
一度一から書き直したほうがいいのでしょうか…?

ひぐらし
記事: 5
登録日時: 11年前

Re: Win32APIにおける、MDIWindow形成について

#7

投稿記事 by ひぐらし » 11年前

追記なのですが、他のパソコンで同じコードを試したところ エラーを吐き出さずに出来ました。
もうわけがわからなくなってきました…

ちなみに、その実行できたパソコンもVisual Studio 2010のwindows 7です。

taketoshi
記事: 222
登録日時: 14年前
住所: 日本国

Re: Win32APIにおける、MDIWindow形成について

#8

投稿記事 by taketoshi » 11年前

頂いている情報ですとコードの問題というより、VSやPCの設定しか疑うところがありません。

設定の問題だと新たにイチから書き直さずともソリューションを組みなおす
(新規にVSでファイルを作成しそこに既存のcppを組み込みなおす)でも直る気はします。

動く形で上げていただければこちらでも検証してみます。
当方Windows7です。

閉鎖

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