⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 odbc5.html

📁 win32汇编教程 希望各位多多支持
💻 HTML
📖 第 1 页 / 共 2 页
字号:
	.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
		invoke SQLExecDirect, hStmt, addr SQLStatement, sizeof SQLStatement
		.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
			invoke FillData
		.else
			invoke ShowWindow, hList, SW_HIDE
			invoke MessageBox,hDlg,addr ExecuteFail, addr AppName, MB_OK+MB_ICONERROR
		.endif
		invoke SQLCloseCursor, hStmt
		invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
	.else
		invoke ShowWindow, hList, SW_HIDE
		invoke MessageBox,hDlg,addr AllocStmtFail, addr AppName, MB_OK+MB_ICONERROR
	.endif
	ret
RunQuery endp
QueryProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD	
	.if uMsg==WM_CLOSE
		invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
		invoke EndDialog, hDlg,0
	.elseif uMsg==WM_INITDIALOG
		invoke ShowWindow, hList, SW_SHOW
		invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
		.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
			invoke lstrcpy, addr Conn, addr SQLStatement
			invoke lstrcat, addr Conn, addr WhereStatement
			invoke SQLBindParameter,hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,25,0, addr SearchName,25,addr StrLen
			invoke SQLPrepare, hStmt, addr Conn, sizeof Conn
		.else
			invoke ShowWindow, hList, SW_HIDE
			invoke MessageBox,hDlg,addr AllocStmtFail, addr AppName, MB_OK+MB_ICONERROR
			invoke EndDialog, hDlg,0
		.endif	
	.elseif uMsg==WM_COMMAND
		mov eax, wParam
		shr eax,16
		.if ax==BN_CLICKED
			mov eax,wParam
			.if ax==IDC_OK
				invoke GetDlgItemText, hDlg, IDC_NAME, addr SearchName, 25
				.if ax==0
					invoke MessageBox, hDlg,addr NoData, addr AppName, MB_OK+MB_ICONERROR
					invoke GetDlgItem, hDlg, IDC_NAME
					invoke SetFocus, eax
				.else
					invoke lstrlen,addr SearchName
					mov StrLen,eax
					invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0
					invoke SQLExecute, hStmt
					invoke FillData
					invoke SQLCloseCursor, hStmt
				.endif
			.else
				invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt
				invoke EndDialog, hDlg,0
			.endif
		.endif
	.else
		mov eax,FALSE
		ret
	.endif
	mov eax,TRUE
	ret
QueryProc endp
end start</b></font>
</pre>
<h4><font face="Tahoma" color="#FFFFCC">Analysis</font></h4>
<pre><b><font face="Tahoma" color="#33CCCC">start:
	invoke GetModuleHandle, NULL
	mov hInstance,eax
	call GetProgramPath</font></b></pre>
<p><font face="Tahoma" size="-1">When the program starts, it obtains the instance 
  handle and then finds out its own path. The assumption is that the database, 
  test.mdb, would be in the same folder as the program. </font><br>
</p>
<pre><font face="Tahoma"><b><font color="#33CCCC">GetProgramPath proc
	invoke GetModuleFileName, NULL,addr ProgPath,sizeof ProgPath
	std
	mov edi,offset ProgPath
	add edi,sizeof ProgPath-1
	mov al,"\"
	mov ecx,sizeof ProgPath
	repne scasb
	cld
	mov byte ptr [edi+2],0
	ret
GetProgramPath endp</font></b></font> </pre>
<p><font face="Tahoma" size="-1">GetProgramPath calls GetModuleFileName to obtain 
  the full pathname of the program. After that, it searchs for the last &quot;\&quot; 
  in the pathname so that it can &quot;truncate&quot; the filename from the path 
  by replacing the first character of the filename with 0. Thus we got the path 
  of the program in ProgPath.</font></p>
<p><font face="Tahoma" size="-1">The program then displays the main dialog box 
  with <font color="#FFFFCC"><b>DialogBoxParam</b></font>. The first time the 
  main dialog box is loaded, it obtains the menu handle and the handle to the 
  listview control. It next inserts three columns into the listview control (because 
  we know beforehand that the result set consists of three columns. After all 
  we are the one who created the table in the first place.)</font></p>
<p><font face="Tahoma" size="-1">After that, it waits for the user's action. If 
  the user selects &quot;connect&quot; from the menu, it calls <font color="#FFFFCC"><b>ODBCConnect</b></font> 
  function.</font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">ODBCConnect proc hDlg:DWORD
	invoke SQLAllocHandle, SQL_HANDLE_ENV, SQL_NULL_HANDLE, addr hEnv
	.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">The first thing it does is to allocate 
  an environment handle with <font color="#FFFFCC"><b>SQLAllocHandle</b></font>.</font><b><font color="#33CCCC"><br>
  </font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">		invoke SQLSetEnvAttr, hEnv,SQL_ATTR_ODBC_VERSION, SQL_OV_ODBC3,0
		.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">After it obtained the environment handle, 
  it specifies that it wants to use ODBC 3.x syntax by calling <font color="#FFFFCC"><b>SQLSetEnvAttr</b></font>.</font><b><font color="#33CCCC"><br>
  </font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">			invoke SQLAllocHandle, SQL_HANDLE_DBC, hEnv, addr hConn
			.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">If all goes well, it can begin the connection 
  attempt by allocating a connection handle with <font color="#FFFFCC"><b>SQLAllocHandle</b></font>.</font><b><font color="#33CCCC"><br>
  </font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">				invoke lstrcpy,addr ConnectString,addr strConnect
				invoke lstrcat,addr ConnectString, addr ProgPath
				invoke lstrcat, addr ConnectString,addr DBName</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">Con</font><font size="-1">struct the connection 
  string. The final connection string we will use is in ConnectionString </font><b><font color="#33CCCC"><br>
  </font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">				invoke SQLDriverConnect, hConn, hDlg, addr ConnectString, sizeof ConnectString, addr Conn, sizeof Conn,addr StrLen, SQL_DRIVER_COMPLETE
				.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
					invoke SwitchMenuState,TRUE
					invoke MessageBox,hDlg, addr Conn,addr ConnectCaption,MB_OK+MB_ICONINFORMATION</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">When the connection string is ready, it 
  calls <font color="#FFFFCC"><b>SQLDriverConnect</b></font> to attempt to connect 
  to test.mdb with MS Access ODBC driver. If test.mdb is not found, the ODBC driver 
  will prompt the user for its location because we specify <font color="#CCFFCC"><b>SQL_DRIVER_COMPLETE</b></font> 
  flag. When SQLDriverConnect returned successfully, Conn is filled with the complete 
  connection string constructed by the ODBC driver. We display that string to 
  the user with a message box. SwitchMenuState is a simple function that enables/grays 
  out the appropriate menu items.</font></font></p>
<p><font face="Tahoma" size="-1">Right now, the connection to the database is 
  open until the user chooses to close it. </font></p>
<p><font face="Tahoma" size="-1">When the user selects &quot;View All Records&quot;, 
  the dialog box procedure calls RunQuery.</font><font face="Tahoma"><b><font color="#33CCCC"> 
  <br>
  </font></b></font></p>
<pre><font face="Tahoma"><b>
<font color="#33CCCC">RunQuery proc hDlg:DWORD
	invoke ShowWindow, hList, SW_SHOW
	invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0</font></b></font></pre>
<p><font face="Tahoma">Since the listview control is created hidden, it's now 
  the time to show it. Also we need to delete all items (if any) from the listview 
  control.<b><font color="#33CCCC"><br>
  </font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">	invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
	.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">Next, the program allocates a statement 
  handle. </font><b><br>
  <font color="#33CCCC"> </font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">		invoke SQLExecDirect, hStmt, addr SQLStatement, sizeof SQLStatement
		.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">Execute the premade SQL statement with 
  <font color="#FFFFCC"> <b>SQLExecDirect</b></font>. I choose to use <font color="#FFFFCC"><b>SQLExecDirect</b></font> 
  here because thiis SQL statement is usually called only once.</font><b><font color="#33CCCC"><br>
  </font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">			invoke FillData</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">After executing the SQL statement, a result 
  set should be returned. We extract the data in the result set into the listview 
  control in FillData function.</font></font></p>
<pre><font face="Tahoma"><font face="Tahoma"><b><font color="#33CCCC">FillData proc
	LOCAL lvi:LV_ITEM
	LOCAL row:DWORD

	invoke SQLBindCol, hStmt,1,SQL_C_CHAR, addr TheName, sizeof TheName,addr NameLength
	invoke SQLBindCol, hStmt,2,SQL_C_CHAR, addr TheSurname, sizeof TheSurname,addr SurnameLength
	invoke SQLBindCol, hStmt,3,SQL_C_CHAR, addr TelNo, sizeof TelNo,addr TelNoLength</font></b></font></font></pre>
<p><font face="Tahoma"><font face="Tahoma" size="-1">Here, the result set is returned. 
  We need to bind all three columns of the result set to the buffers we provided. 
  We call <font color="#FFFFCC"><b>SQLBindCol</b></font> to do that. Note that 
  we need a separate call for each column. And we need not bind ALL columns: only 
  the columns we need to obtain the data from. </font><font face="Tahoma"><b><br>
  </b></font></font></p>
<pre><font face="Tahoma"><font face="Tahoma"><b><font color="#33CCCC">	mov row,0
	.while TRUE
		mov byte ptr ds:[TheName],0
		mov byte ptr ds:[TheSurname],0
		mov byte ptr ds:[TelNo],0</font></b></font></font></pre>
<p><font face="Tahoma"><font face="Tahoma" size="-1">We initialize the buffers 
  to NULLs in case there is no data in the column(s). The better way is to use 
  the length of data returned in the variables you specified in <font color="#FFFFCC"><b>SQLBindCol</b></font>. 
  In our example, we could check the values in <font color="#CCFFCC"><b>NameLength</b></font>, 
  <font color="#CCFFCC"> <b>SurnameLength</b></font> and <font color="#CCFFCC"><b>TelNoLength</b></font> 
  for the actual length of the strings returned.</font><font face="Tahoma"><b> 
  </b></font></font></p>
<pre><font face="Tahoma"><font face="Tahoma"><b><font color="#33CCCC">		invoke SQLFetch, hStmt
		.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
			mov lvi.imask,LVIF_TEXT+LVIF_PARAM
			push row
			pop lvi.iItem	
			mov lvi.iSubItem,0
			mov lvi.pszText, offset TheName
			push row
			pop lvi.lParam
			invoke SendMessage,hList, LVM_INSERTITEM,0, addr lvi</font></b></font><font size="-1" color="#33CCCC">   </font><font color="#33CCCC"><b> </b></font></font></pre>
<p><font face="Tahoma"><font size="-1">The rest is simple. Call <font color="#FFFFCC"><b>SQLFetch 
  </b></font>to retrieve a row from the result set and then store the values in 
  the buffers into the listview control. When no more row is available (we have 
  reached the end of file), <font color="#FFFFCC"><b>SQLFetch</b></font> returns 
  <font color="#CCFFCC"><b>SQL_NO_DATA</b></font> and we exit the infinite loop.</font></font><font face="Tahoma"><b><font color="#33CCCC"> 
  </font></b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">		invoke SQLCloseCursor, hStmt
		invoke SQLFreeHandle, SQL_HANDLE_STMT, hStmt</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">When we are done with the result set, we 
  must close it with <font color="#FFFFCC"><b>SQLCloseCursor</b></font> and then 
  free the statement handle with <font color="#FFFFCC"><b>SQLFreeHandle</b></font>.</font><font face="Tahoma" size="-1"><font color="#33CCCC"><br>
  </font></font><font color="#33CCCC" face="Tahoma" size="-1"><br>
  </font><font face="Tahoma" size="-1">When the user selects &quot;Query&quot; 
  menu item, the program displays another dialog box prompting the user for the 
  name to search for.</font></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">	.elseif uMsg==WM_INITDIALOG
		invoke ShowWindow, hList, SW_SHOW
		invoke SQLAllocHandle, SQL_HANDLE_STMT, hConn, addr hStmt
		.if ax==SQL_SUCCESS || ax==SQL_SUCCESS_WITH_INFO
			invoke lstrcpy, addr Conn, addr SQLStatement
			invoke lstrcat, addr Conn, addr WhereStatement
			invoke SQLBindParameter,hStmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR,25,0, addr SearchName,25,addr StrLen
			invoke SQLPrepare, hStmt, addr Conn, sizeof Conn</font></b></font></pre>
<p><font face="Tahoma" size="-1">The first thing the dialog box does is to show 
  the listview control. It then allocates a statement handle, create an SQL statement. 
  This SQL statement has the &quot;where&quot; clause with a parameter marker,?. 
  The full SQL statement is:</font></p>
<blockquote> 
  <p><font face="Tahoma"><b>select * from main where name=?</b></font></p>
</blockquote>
<p><font size="-1" face="Tahoma">Next, it calls <font color="#FFFFCC"><b>SQLBindParameter</b></font> 
  to associate the parameter marker with the buffer, <font color="#CCFFCC"><b>SearchName</b></font>, 
  so that when the SQL statement is executed, the ODBC driver can obtain the string 
  it needs to use from <font color="#CCFFCC"><b>SearchName</b></font>. Afer that, 
  it calls <font color="#FFFFCC"><b>SQLPrepare</b></font> to compile the SQL statement. 
  The rationale is that, you prepare/compile the SQL statement only once and then 
  you execute it many times. Since the SQL statement was compiled, the subsequent 
  execution is faster.</font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">			.if ax==IDC_OK
				invoke GetDlgItemText, hDlg, IDC_NAME, addr SearchName, 25
				.if ax==0
					invoke MessageBox, hDlg,addr NoData, addr AppName, MB_OK+MB_ICONERROR
					invoke GetDlgItem, hDlg, IDC_NAME
					invoke SetFocus, eax
				.else</font></b></font></pre>
<p><font face="Tahoma"><font size="-1">When the user typed some name in the edit 
  control and pressed return key, the program retrieves the text from the edit 
  control and checks if it's a NULL string. If so, it displays a message box and 
  sets the keyboard focus to the edit control to prompt the user for a name.<br>
  </font><b> </b></font></p>
<pre><font face="Tahoma"><b><font color="#33CCCC">					invoke lstrlen,addr SearchName
					mov StrLen,eax
					invoke SendMessage, hList, LVM_DELETEALLITEMS,0,0
					invoke SQLExecute, hStmt
					invoke FillData
					invoke SQLCloseCursor, hStmt</font></b></font></pre>
<p><font face="Tahoma" size="-1">If a name is typed into the edit control, we 
  find out its length and store the value into <font color="#CCFFCC"><b>StrLen</b></font> 
  for use by ODBC driver (remember that we passed the address of StrLen to <font color="#FFFFCC"><b>SQLBindParameter</b></font>). 
  Then it calls <font color="#FFFFCC"><b>SQLExecute</b></font> on the statement 
  handle to execute the prepared SQL statement. When<font color="#FFFFCC"><b> 
  SQLExecute</b></font> returns, it calls FillData to display the result in the 
  listview control. Since we have no use for the result set anymore, we close 
  it by calling <font color="#FFFFCC"><b>SQLCloseCursor</b></font>.</font></p>
<hr>
<p align="center"><font face="Tahoma" size="-1"><b>[<a href="http://win32asm.cjb.net">Iczelion's 
  Win32 Assembly Homepage</a>]</b></font></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</body>
</html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -