CallBack関数でアクセス違反が起きる

ActiveBasicでのプログラミングでわからないこと、困ったことなどがあったら、ここで質問してみましょう(質問を行う場合は、過去ログやWeb上であらかじめ問題を整理するようにしましょう☆)。
返信する
メッセージ
作成者
yu0627
記事: 154
登録日時: 2005年5月31日(火) 14:53

CallBack関数でアクセス違反が起きる

#1 投稿記事 by yu0627 »

コード: 全て選択

Case IDM_MACRO
  MainWnd_IDM_MACRO_MenuClick()
End Select
この部分でアクセス違反がなぜか起こります。
参考に呼び出すソースを載せます。
このアルゴリズムはマクロを実行するものです。

コード: 全て選択

Sub MainWnd_IDM_MACRO_MenuClick()
	'変数宣言
	Dim ofn As OPENFILENAME				'OPENFILENAME構造体
	Dim FileName[MAX_PATH-1] As Byte	'ファイル名
	Dim hFile As Long					'ファイルハンドル
	Dim dwFileSize As  DWord			'ファイルサイズ
	Dim dwAccessByte As DWord			'ファイル アクセスサイズ
	Dim buffer As BytePtr				'バッファポインタ
	Dim buffer2 As BytePtr
	Dim buffer3 As BytePtr
	Dim tempLong As DWord
	Dim buffertemp As String			'文字列一時保管
	Dim i As Long, i2 As Long
	Dim crlf As Long					'改行の位置
	Dim temp As String, temp2 As Long
	Dim sw As Long, sw2 As Long			'フラグ
	Dim MainLong As DWord
	Dim Length As DWord
	Dim SendParam As SendParam

	'OPENFILENAME構造体の初期化
	FillMemory(VarPtr(ofn), Len(ofn), 0)
	ofn.lStructSize=Len(ofn)
	ofn.hwndOwner=hMainWnd
	ofn.lpstrFilter=Ex"マクロ ファイル(*.mcr)\0*.mcr\0\0"
	ofn.nFilterIndex=1
	ofn.lpstrFile=FileName
	ofn.nMaxFile=MAX_PATH
	ofn.lpstrTitle="マクロファイルを指定"
	ofn.Flags=OFN_FILEMUSTEXIST or OFN_HIDEREADONLY or OFN_PATHMUSTEXIST
	ofn.lpstrDefExt=""

	'「ファイルを開く」ダイアログボックスを開く
	If GetOpenFileName(ofn)=0 Then Exit Sub

	'ファイルを開く
	hFile=CreateFile(ofn.lpstrFile, GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
		ByVal 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
	If hFile=INVALID_HANDLE_VALUE Then
		'ファイルオープンに失敗した時
		CloseHandle(hFile)
		MessageBox(hMainWnd, "ファイルのオープンに失敗", "Error - LightMailSender", MB_OK or MB_ICONSTOP)
		Exit Sub
	End If

	'ファイルサイズを取得し、バッファを確保
	dwFileSize = GetFileSize(hFile, 0)
	buffer = malloc(dwFileSize + 1)

	'ファイルの内容をbufferに読み込む
	ReadFile(hFile, buffer, dwFileSize, VarPtr(dwAccessByte), ByVal 0)

	CloseHandle(hFile)
	
	'ここから繰り返し
	Do
		'改行文字列(\r\n)の位置を探す
    	crlf = InStr(1, buffer, Ex"\r\n")

		'bufferから改行までの一列を取り出す
		temp=Mid$(buffer, 1, crlf)
		If memicmp(temp, "send", 4)<>0 and sw=1 Then
			sw=0
		End If
		If memicmp(temp, "SetSMTPServerName:", 18)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 19)
			temp[Len(temp)-1]=0
			SetDlgItemText(hMainWnd, EditBox_SMTPServer, temp)
		ElseIf memicmp(temp, "SetFromAddress:", 15)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 16)
			temp[Len(temp)-1]=0
			SetDlgItemText(hMainWnd, EditBox_FromAddress, temp)
		ElseIf memicmp(temp, "SetFromName:", 12)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 13)
			temp[Len(temp)-1]=0
		ElseIf memicmp(temp, "SetToAddress:", 13)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 14)
			temp[Len(temp)-1]=0
			SetDlgItemText(hMainWnd, EditBox_ToAddress, temp)
		ElseIf memicmp(temp, "SetToName:", 10)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 11)
			temp[Len(temp)-1]=0
			SetDlgItemText(hMainWnd, EditBox_ToName, temp)
		ElseIf memicmp(temp, "POPbeforeSMTP:Yes", 17)=0 Then
			temp2=Len(temp)+2
			i2=1
			SendDlgItemMessage(hMainWnd, PBSCheckBox, BM_SETCHECK, 1, 0)
			MainWnd_PBSCheckBox_Click()
		ElseIf memicmp(temp, "POPbeforeSMTP:No", 16)=0 Then
			temp2=Len(temp)+2
			i2=1
			SendDlgItemMessage(hMainWnd, PBSCheckBox, BM_SETCHECK, 0, 0)
			MainWnd_PBSCheckBox_Click()
		ElseIf memicmp(temp, "SetPOPServerName:", 17)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 18)
			temp[Len(temp)-1]=0
			SetDlgItemText(hMainWnd, POPServerName_EditBox, temp)
		ElseIf memicmp(temp, "SetUserID:", 10)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 11)
			temp[Len(temp)-1]=0
			SetDlgItemText(hMainWnd, UserID_EditBox, temp)
		ElseIf memicmp(temp, "SetPassword:", 12)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 13)
			temp[Len(temp)-1]=0
			SetDlgItemText(hMainWnd, PassWord_EditBox, temp)
		ElseIf memicmp(temp, "send", 4)=0 and sw=0 Then
			sw=1
			temp2=Len(temp)+2
			SendParam.sw=1
			GetDlgItemText(hMainWnd, EditBox_SMTPServer, VarPtr(SendParam.SMTPServerName), 256)
			GetDlgItemText(hMainWnd, EditBox_FromAddress, VarPtr(SendParam.FromAddress), 256)
			GetDlgItemText(hMainWnd, EditBox_FromName, VarPtr(SendParam.FromName), 256)
			GetDlgItemText(hMainWnd, EditBox_ToAddress, VarPtr(SendParam.ToAddress), 256)
			GetDlgItemText(hMainWnd, EditBox_ToName, VarPtr(SendParam.ToName), 256)
			GetDlgItemText(hMainWnd, EditBox_Subject, VarPtr(SendParam.Subject), 256)
			GetDlgItemText(hMainWnd, POPServerName_EditBox, VarPtr(SendParam.POPServerName), 256)
			GetDlgItemText(hMainWnd, UserID_EditBox, VarPtr(SendParam.UserID), 256)
			GetDlgItemText(hMainWnd, PassWord_EditBox, VarPtr(SendParam.PassWord), 256)
			Length=GetWindowTextLength(GetDlgItem(hMainWnd, EditBox_Main))
			SendParam.Main=ZeroString(Length+1)
			GetWindowText(GetDlgItem(hMainWnd, EditBox_Main), StrPtr(SendParam.Main), Length)
			SendMail(SendParam)
		ElseIf memicmp(temp, "send", 4)=0 and sw=1 Then
			MessageBox(hMainWnd, "sendコマンドは連続使用できません。", "LightMailSender", MB_OK)
			Exit Sub
		ElseIf memicmp(temp, "SetSubject:", 11)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 12)
			temp[Len(temp)-1]=0
			SetDlgItemText(hMainWnd, EditBox_Subject, temp)
		ElseIf memicmp(temp, "SetMain:", 8)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 9)
			SetDlgItemText(hMainWnd, EditBox_Main, temp)
		ElseIf memicmp(temp, "AddMain:", 8)=0 Then
			temp2=Len(temp)+2
			temp=Mid$(temp, 9)
			tempLong=GetWindowTextLength(GetDlgItem(hMainWnd, EditBox_Main))
			buffer2=malloc(tempLong)
			GetDlgItemText(hMainWnd, EditBox_Main, buffer2, tempLong)
			buffer3=malloc(Len(buffer2) + Len(temp) + 2)
			lstrcpy(buffer3, buffer2 + Ex"\r\n" + temp)
			SetDlgItemText(hMainWnd, EditBox_Main, buffer3)
		ElseIf memicmp(temp, "End", 3)=0 Then
			Exit Sub
		Else
			Exit Do
		End If

		'バッファから取得した一行を除き、bufferにコピー
		buffertemp=Mid$(MakeStr(buffer), temp2)
		lstrcpy(buffer, StrPtr(buffertemp))
	Loop
End Sub
ちなみに構造体SendParamの宣言は以下のようになっています。

コード: 全て選択

Type SendParam
	sw As Long
	SMTPServerName[255] As Byte
	FromAddress[255] As Byte
	FromName[255] As Byte
	ToAddress[255] As Byte
	ToName[255] As Byte
	POPServerName[255] As Byte
	UserID[255] As Byte
	PassWord[255] As Byte
	Subject[255] As Byte
	Main As String
End Type
どこがおかしいでしょうか。
xsb007

Re: CallBack関数でアクセス違反が起きる

#2 投稿記事 by xsb007 »

> buffer2=malloc(tempLong)
\0の分のメモリが確保されていません。tempLong+1にする必要があります。

> buffer3=malloc(Len(buffer2) + Len(temp) + 2)
こちらも\0の分のメモリが確保されていません。+2ではなく+3にしなければなりません。

今のところ、気になるのはこの二か所ですが、まだ問題がある可能性があります。
yu0627
記事: 154
登録日時: 2005年5月31日(火) 14:53

返信@yu0627

#3 投稿記事 by yu0627 »

返信ありがとうございます。修正してみました。しかし、また同じところでエラーがでます。
また、以下の内容もデバッガで引っかかります。

コード: 全て選択

DispatchMessage(msgMain)
返信する