青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

在 Windows CE 下自帶有無線網(wǎng)卡的配置和連接程序,可是我的系統(tǒng)剪裁掉了資源管理器和任務(wù)欄,導(dǎo)致自帶的無線網(wǎng)卡配置程序不能再使用了,只好自力更生。

我的環(huán)境是 S3C2440 + WinCE 5.0 + VNUWCL5(威盛無線網(wǎng)卡)及驅(qū)動程序。使用 Automatic Configuration Functions API

一、枚舉系統(tǒng)中可用的無線網(wǎng)絡(luò)設(shè)備

      下面的函數(shù)可以枚舉出系統(tǒng)中所有可用的無線網(wǎng)卡設(shè)備的GUID,為了簡化,我選擇第一塊可用的無線網(wǎng)卡來操作      

BOOL GetFirstWirelessCard(PTCHAR pCard)
{
if (!pCard)
{
return FALSE;
}
INTFS_KEY_TABLE IntfsTable;
IntfsTable.dwNumIntfs = 0;
IntfsTable.pIntfs = NULL;
_tcscpy(pCard, TEXT(""));
// 枚舉系統(tǒng)中可用的無線網(wǎng)卡
DWORD dwStatus = WZCEnumInterfaces(NULL, &IntfsTable);
if (dwStatus != ERROR_SUCCESS)
{
RETAILMSG(DBG_MSG, (TEXT("WZCEnumInterfaces() error 0x%08X\n"),dwStatus));
return FALSE;
}
// 判斷無線網(wǎng)卡的數(shù)量,可以根據(jù)無線網(wǎng)卡數(shù)量來枚舉出所有可用的無線網(wǎng)卡
if (!IntfsTable.dwNumIntfs)
{
RETAILMSG(DBG_MSG, (TEXT("System has no wireless card.\n")));
return FALSE;
}
_tcscpy(pCard, IntfsTable.pIntfs[0].wszGuid);
LocalFree(IntfsTable.pIntfs);
return TRUE;
}

 二、獲取無線網(wǎng)絡(luò)信息

        獲取到了系統(tǒng)可用的無線網(wǎng)卡后,我們就可以利用它的 GUID 號來進(jìn)行進(jìn)一步的操作了,首先要做的事情就是得到該無線網(wǎng)卡的信息以及該無線網(wǎng)卡掃描到的 WIFI 網(wǎng)關(guān)信息。

        以下函數(shù)可以獲取到該無線網(wǎng)卡及掃描的到的無線 AP 信息

//////////////////////////////////////////////////////////////////////////
// pCard: 無線網(wǎng)卡GUID
// pIntf: 無線網(wǎng)卡配置信息結(jié)果體
// pOutFlags: 網(wǎng)卡配置信息掩碼標(biāo)志
//////////////////////////////////////////////////////////////////////////
BOOL GetWirelessCardInfo(PTCHAR pCard, PINTF_ENTRY_EX pIntf, PDWORD pOutFlags)
{
TCHAR *szWiFiCard = NULL;
// 參數(shù)校驗
if (!pCard || !pIntf || !pOutFlags)
{
RETAILMSG(DBG_MSG, (TEXT("Param Error.\n")));
return FALSE;
}
szWiFiCard = pCard;
*pOutFlags = 0;
// 初始化無線網(wǎng)卡信息
ZeroMemory(pIntf, sizeof(INTF_ENTRY_EX));
// 設(shè)置GUID 號
pIntf->wszGuid = szWiFiCard;
// 查詢無線網(wǎng)卡信息
DWORD dwStatus = WZCQueryInterfaceEx(NULL, INTF_ALL, pIntf, pOutFlags);
if (dwStatus != ERROR_SUCCESS)
{
RETAILMSG(DBG_MSG, (TEXT("WZCQueryInterfaceEx() error 0x%08X\n"), dwStatus));
return FALSE;
}
return TRUE;
}

三、判斷連接狀態(tài)

        我們可以通過無線網(wǎng)卡的狀態(tài)來判斷當(dāng)前無線網(wǎng)卡是否已經(jīng)和無線AP建立了連接

BOOL IsAssociated(const INTF_ENTRY_EX Intf, const DWORD dwOutFlags)
{
if (dwOutFlags & INTF_BSSID)
{
PRAW_DATA prdMAC = (PRAW_DATA)(&Intf.rdBSSID);
// 判斷BSSID 的MAC 地址是否有效來判斷是否和無線AP建立了連接
if (prdMAC == NULL || prdMAC->dwDataLen == 0 ||
(!prdMAC->pData[0] && !prdMAC->pData[1] && !prdMAC->pData[2] &
!prdMAC->pData[3] && !prdMAC->pData[4] && !prdMAC->pData[5]))
{
RETAILMSG(DBG_MSG, (TEXT("(This wifi card is not associated to any)\n")));
return FALSE;
}
else
{
RETAILMSG(DBG_MSG, (TEXT("(This wifi card is associated state)\n")));
return TRUE;
}
}
else
{
return FALSE;
}
}

四、獲取無線AP信息

        獲取了無線網(wǎng)卡的信息后,可以通過無線網(wǎng)卡枚舉出當(dāng)前所有可用的無線AP的SSID名稱以及加密模式等等所有可用信息,一下函數(shù)可以實現(xiàn)該功能

void GetWirelseeListSSID(const PRAW_DATA prdBSSIDList, HWND hListCtlWnd)
{
if (prdBSSIDList == NULL || prdBSSIDList->dwDataLen  == 0)
{
RETAILMSG(DBG_MSG, (TEXT("<null> entry.\n")));
}
else
{
PWZC_802_11_CONFIG_LIST pConfigList = (PWZC_802_11_CONFIG_LIST)prdBSSIDList->pData;
//RETAILMSG(DBG_MSG, (TEXT("[%d] entries.\n"), pConfigList->NumberOfItems));
uint i;
// 枚舉所有無線AP
for (i = 0; i < pConfigList->NumberOfItems; i++)
{
PWZC_WLAN_CONFIG pConfig = &(pConfigList->Config[i]);
RAW_DATA rdBuffer;
rdBuffer.dwDataLen = pConfig->Ssid.SsidLength;
rdBuffer.pData = pConfig->Ssid.Ssid;
TCHAR tSsid[MAX_PATH];
// 將SSID 的ASCII 碼轉(zhuǎn)化成字符串
PrintSSID(&rdBuffer, tSsid);
if (hListCtlWnd)
{
if (ListBox_FindString(hListCtlWnd, 0, tSsid) == LB_ERR)
{
ListBox_AddString(hListCtlWnd, tSsid);
}
}
//RETAILMSG(DBG_MSG, (TEXT("\n")));
}
}
}

五、連接到指定的無線AP

//////////////////////////////////////////////////////////////////////////
// pCard: 無線網(wǎng)卡GUID
// pSSID: 無線AP SSID號
// bAdhoc: 是否點對點的WIFI 連接
// ulPrivacy: 加密模式(WEP/WPA....)
// ndisMode: 認(rèn)證模式(Open/Share)
// iKeyIndex: 密鑰索引(1-4)
// pKey: 密碼
// iEapType: 802.11 認(rèn)證模式
//////////////////////////////////////////////////////////////////////////
BOOL WirelessConnect(PTCHAR pCard, PTCHAR pSSID, BOOL bAdhoc, ULONG ulPrivacy, NDIS_802_11_AUTHENTICATION_MODE ndisMode, int iKeyIndex, PTCHAR pKey, int iEapType)
{
BOOL bRet = FALSE;
if (!pSSID)
{
RETAILMSG(DBG_MSG, (TEXT("Param Error.\n")));
return FALSE;
}
else
{
WZC_WLAN_CONFIG wzcConfig;
ZeroMemory(&wzcConfig, sizeof(WZC_WLAN_CONFIG));
wzcConfig.Length = sizeof(WZC_WLAN_CONFIG);
wzcConfig.dwCtlFlags = 0;
wzcConfig.Ssid.SsidLength = _tcslen(pSSID);
for (UINT i = 0; i < wzcConfig.Ssid.SsidLength; i++)
{
wzcConfig.Ssid.Ssid[i] = (CHAR)pSSID[i];
}
if (bAdhoc)
{
wzcConfig.InfrastructureMode = Ndis802_11IBSS;
}
else
{
wzcConfig.InfrastructureMode = Ndis802_11Infrastructure;
}
wzcConfig.AuthenticationMode = ndisMode;
wzcConfig.Privacy = ulPrivacy;
if (pKey == NULL || _tcslen(pKey) == 0)
{
// 對密鑰進(jìn)行轉(zhuǎn)換
bRet = InterpretEncryptionKeyValue(wzcConfig, 0, NULL, TRUE);
wzcConfig.EapolParams.dwEapType = iEapType;
wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;
wzcConfig.EapolParams.bEnable8021x  = TRUE;
wzcConfig.EapolParams.dwAuthDataLen = 0;
wzcConfig.EapolParams.pbAuthData = 0;
}
else
{
RETAILMSG(DBG_MSG, (TEXT("WirelessConnect iKeyIndex = %d.\n"), iKeyIndex));
bRet = InterpretEncryptionKeyValue(wzcConfig, iKeyIndex, pKey, FALSE);
}
// 連接到指定的無線AP,并將該AP添加到首先無線AP中
AddToPreferredNetworkList(pCard, wzcConfig, pSSID);
}
return bRet;
}

六、密鑰轉(zhuǎn)換

        輸入的密鑰需要通過加密方式進(jìn)行一定的轉(zhuǎn)化,以下函數(shù)可以完成改功能

static void EncryptWepKMaterial(IN OUT WZC_WLAN_CONFIG* pwzcConfig)
{
BYTE chFakeKeyMaterial[] = { 0x56, 0x09, 0x08, 0x98, 0x4D, 0x08, 0x11, 0x66, 0x42, 0x03, 0x01, 0x67, 0x66 };
for (int i = 0; i < WZCCTL_MAX_WEPK_MATERIAL; i++)
pwzcConfig->KeyMaterial[i] ^= chFakeKeyMaterial[(7*i)%13];
}
BOOL InterpretEncryptionKeyValue(IN OUT WZC_WLAN_CONFIG& wzcConfig, IN int iKeyIndex, IN PTCHAR pKey, IN BOOL bNeed8021X)
{
if(wzcConfig.Privacy == Ndis802_11WEPEnabled)
{
if(!bNeed8021X && pKey)
{
wzcConfig.KeyIndex = iKeyIndex;
wzcConfig.KeyLength = _tcslen(pKey);
if((wzcConfig.KeyLength == 5) || (wzcConfig.KeyLength == 13))
{
for(UINT i=0; i<wzcConfig.KeyLength; i++)
wzcConfig.KeyMaterial[i] = (UCHAR)pKey[i];
}
else
{
if((pKey[0] != TEXT('0')) || (pKey[1] != TEXT('x')))
{
RETAILMSG(DBG_MSG, (TEXT("Invalid key value.\n")));
return FALSE;
}
pKey += 2;
wzcConfig.KeyLength = wcslen(pKey);
if((wzcConfig.KeyLength != 10) && (wzcConfig.KeyLength != 26))
{
RETAILMSG(DBG_MSG, (TEXT("Invalid key value.\n")));
return FALSE;
}
wzcConfig.KeyLength >>= 1;
for(UINT i=0; i<wzcConfig.KeyLength; i++)
{
wzcConfig.KeyMaterial[i] = (HEX(pKey[2 * i]) << 4) | HEX(pKey[2 * i + 1]);
}
}
EncryptWepKMaterial(&wzcConfig);
wzcConfig.dwCtlFlags |= WZCCTL_WEPK_PRESENT;
}
}
else if(wzcConfig.Privacy == Ndis802_11Encryption2Enabled
|| wzcConfig.Privacy == Ndis802_11Encryption3Enabled)
{
if(!bNeed8021X)
{
wzcConfig.KeyLength = wcslen(pKey);
if((wzcConfig.KeyLength < 8) || (wzcConfig.KeyLength > 63))
{
RETAILMSG(DBG_MSG, (TEXT("WPA-PSK/TKIP key should be 8-63 char long string.\n")));
return FALSE;
}
char szEncryptionKeyValue8[64]; // longest key is 63
memset(szEncryptionKeyValue8, 0, sizeof(szEncryptionKeyValue8));
WideCharToMultiByte(CP_ACP,
0,
pKey,
wzcConfig.KeyLength + 1,
szEncryptionKeyValue8,
wzcConfig.KeyLength + 1,
NULL,
NULL);
WZCPassword2Key(&wzcConfig, szEncryptionKeyValue8);
EncryptWepKMaterial(&wzcConfig);
wzcConfig.dwCtlFlags |= WZCCTL_WEPK_XFORMAT
| WZCCTL_WEPK_PRESENT
| WZCCTL_ONEX_ENABLED;
}
wzcConfig.EapolParams.dwEapFlags = EAPOL_ENABLED;
wzcConfig.EapolParams.dwEapType = DEFAULT_EAP_TYPE;
wzcConfig.EapolParams.bEnable8021x = TRUE;
wzcConfig.WPAMCastCipher = Ndis802_11Encryption2Enabled;
}
return TRUE;
}

      通過以上操作,完全可以連接到可用的無線AP了,再加上些適當(dāng)?shù)腢I程序,完全可以用來替代 Windows CE 自帶的無線配置程序了,我再連接中放置了一個簡單的而完整的測試程序,相信大家看了以后都知道怎么操作無線網(wǎng)卡了

http://download.csdn.net/source/927575

posted @ 2010-12-16 09:31 wrh 閱讀(1668) | 評論 (0)編輯 收藏
Note:需CE4.0或更高版本(兼容NDIS5.1)支持
一、加入頭文件
#include <winioctl.h>
#include <ntddndis.h>
#include <nuiouser.h>
二、Attach to NDISUIO
HANDLE hNdis = ::CreateFile( NDISUIO_DEVICE_NAME, GENERIC_ALL, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,
(HANDLE)INVALID_HANDLE_VALUE );

三、獲取設(shè)備名稱

UCHAR                  cbQueryBuffer[ 1024 ];
PNDISUIO_QUERY_BINDING pQueryBinding;
DWORD                  dwBytesReturned = 0;
pQueryBinding = (PNDISUIO_QUERY_BINDING)&cbQueryBuffer[ 0 ];
pQueryBinding->BindingIndex = 0;
if ( ::DeviceIoControl( hNdis,
IOCTL_NDISUIO_QUERY_BINDING,
(LPVOID)&cbQueryBuffer[ 0 ],
sizeof(NDISUIO_QUERY_BINDING),
(LPVOID)&cbQueryBuffer[ 0 ],
sizeof(cbQueryBuffer),
&dwBytesReturned,
NULL ) == TRUE )
{
TCHAR* pDeviceName = (TCHAR*)( cbQueryBuffer + pQueryBinding->DeviceNameOffset );
}

 

四、檢測連接狀態(tài)

NIC_STATISTICS nicStatistics = { 0 };
DWORD          dwBytesReturned = 0;
BOOL bConnected = FALSE;
nicStatistics.ptcDeviceName = pDeviceName;
if ( ::DeviceIoControl( hNdis,
IOCTL_NDISUIO_NIC_STATISTICS,
NULL,
0,
&nicStatistics,
sizeof(NIC_STATISTICS),
&dwBytesReturned,
NULL ) == TRUE )
{
bConnected = ( nicStatistics.MediaState == MEDIA_STATE_CONNECTED );
}

五、獲取信號強度

// example.
// < -90 : No Signal
// < -81 : Very Low
// < -71 : Low
// < -67 : Good
// < -57 : Very Good
// ...   : Excellent
NDISUIO_QUERY_OID ndisQueryOid = { 0 };
DWORD             dwBytesReturned = 0;
int nDb = 0;
ndisQueryOid.Oid = OID_802_11_RSSI;
ndisQueryOid.ptcDeviceName = pDeviceName;
if ( ::DeviceIoControl( hNdis,
IOCTL_NDISUIO_QUERY_OID_VALUE,
(LPVOID)&ndisQueryOid,
sizeof(ndisQueryOid),
(LPVOID)&ndisQueryOid,
sizeof(ndisQueryOid),
&dwBytesReturned,
NULL ) == TRUE )
{
::CopyMemory( &nDb, &ndisQueryOid.Data[ 0 ], sizeof(ULONG) );
}
posted @ 2010-12-16 09:12 wrh 閱讀(1763) | 評論 (1)編輯 收藏


http://msdn.microsoft.com/en-us/library/ms706716(VS.85).aspx

The WlanEnumInterfaces function enumerates all of the wireless LAN interfaces currently enabled on the local computer.

Syntax

DWORD WINAPI WlanEnumInterfaces(
__in        HANDLE hClientHandle,
__reserved  PVOID pReserved,
__out       PWLAN_INTERFACE_INFO_LIST *ppInterfaceList
);

Parameters

hClientHandle [in]

The client's session handle, obtained by a previous call to the WlanOpenHandle function.

pReserved [in]

Reserved for future use. This parameter must be set to NULL.

ppInterfaceList [out]

A pointer to storage for a pointer to receive the returned list of wireless LAN interfaces in a WLAN_INTERFACE_INFO_LIST structure.

The buffer for the WLAN_INTERFACE_INFO_LIST returned is allocated by the WlanEnumInterfaces function if the call succeeds.

Return Value

If the function succeeds, the return value is ERROR_SUCCESS.

If the function fails, the return value may be one of the following return codes.

Return code Description
ERROR_INVALID_PARAMETER

A parameter is incorrect. This error is returned if the hClientHandle or ppInterfaceList parameter is NULL. This error is returned if the pReserved is not NULL. This error is also returned if the hClientHandle parameter is not valid.

ERROR_INVALID_HANDLE

The handle hClientHandle was not found in the handle table.

RPC_STATUS

Various error codes.

ERROR_NOT_ENOUGH_MEMORY

Not enough memory is available to process this request and allocate memory for the query results.

 

Remarks

The WlanEnumInterfaces function allocates memory for the list of returned interfaces that is returned in the buffer pointed to by the ppInterfaceList parameter when the function succeeds. The memory used for the buffer pointed to by ppInterfaceList parameter should be released by calling the WlanFreeMemory function after the buffer is no longer needed.

Examples

The following example enumerates the wireless LAN interfaces on the local computer and prints values from the retrieved WLAN_INTERFACE_INFO_LIST structure and the enumerated WLAN_INTERFACE_INFO structures.

Note  This example will fail to load on Windows Server 2008 and Windows Server 2008 R2 if the Wireless LAN Service is not installed and started.

#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <wlanapi.h>
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
int wmain()
{
// Declare and initialize variables.
HANDLE hClient = NULL;
DWORD dwMaxClient = 2;   //
DWORD dwCurVersion = 0;
DWORD dwResult = 0;
int iRet = 0;
WCHAR GuidString[40] = {0};
int i;
/* variables used for WlanEnumInterfaces  */
PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
PWLAN_INTERFACE_INFO pIfInfo = NULL;
dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
if (dwResult != ERROR_SUCCESS)  {
wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult);
// FormatMessage can be used to find out why the function failed
return 1;
}
dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
if (dwResult != ERROR_SUCCESS)  {
wprintf(L"WlanEnumInterfaces failed with error: %u\n", dwResult);
// FormatMessage can be used to find out why the function failed
return 1;
}
else {
wprintf(L"Num Entries: %lu\n", pIfList->dwNumberOfItems);
wprintf(L"Current Index: %lu\n", pIfList->dwIndex);
for (i = 0; i < (int) pIfList->dwNumberOfItems; i++) {
pIfInfo = (WLAN_INTERFACE_INFO *) &pIfList->InterfaceInfo[i];
wprintf(L"  Interface Index[%d]:\t %lu\n", i, i);
iRet = StringFromGUID2(pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString, 39);
// For c rather than C++ source code, the above line needs to be
// iRet = StringFromGUID2(&pIfInfo->InterfaceGuid, (LPOLESTR) &GuidString, 39);
if (iRet == 0)
wprintf(L"StringFromGUID2 failed\n");
else {
wprintf(L"  InterfaceGUID[%d]: %ws\n",i, GuidString);
}
wprintf(L"  Interface Description[%d]: %ws", i,
pIfInfo->strInterfaceDescription);
wprintf(L"\n");
wprintf(L"  Interface State[%d]:\t ", i);
switch (pIfInfo->isState) {
case wlan_interface_state_not_ready:
wprintf(L"Not ready\n");
break;
case wlan_interface_state_connected:
wprintf(L"Connected\n");
break;
case wlan_interface_state_ad_hoc_network_formed:
wprintf(L"First node in a ad hoc network\n");
break;
case wlan_interface_state_disconnecting:
wprintf(L"Disconnecting\n");
break;
case wlan_interface_state_disconnected:
wprintf(L"Not connected\n");
break;
case wlan_interface_state_associating:
wprintf(L"Attempting to associate with a network\n");
break;
case wlan_interface_state_discovering:
wprintf(L"Auto configuration is discovering settings for the network\n");
break;
case wlan_interface_state_authenticating:
wprintf(L"In process of authenticating\n");
break;
default:
wprintf(L"Unknown state %ld\n", pIfInfo->isState);
break;
}
wprintf(L"\n");
}
}
if (pIfList != NULL) {
WlanFreeMemory(pIfList);
pIfList = NULL;
}
return 0;
}

Requirements

Minimum supported client

Windows Vista, Windows XP with SP3

Minimum supported server

Windows Server 2008

Redistributable

Wireless LAN API for Windows XP with SP2

Header

Wlanapi.h (include Wlanapi.h)

Library

Wlanapi.lib

DLL

Wlanapi.dll
posted @ 2010-12-16 09:01 wrh 閱讀(2667) | 評論 (0)編輯 收藏
用native wifi api吧。
VS2008下:
加入:
#include "Wlanapi.h"
#pragma comment(lib, "Wlanapi.lib")
變量:
DWORD pdwNegotiatedVersion;
HANDLE phClientHandle;
PWLAN_INTERFACE_INFO_LIST wiiList;
然后用下面語句打開handle.
WlanOpenHandle (1,NULL,&pdwNegotiatedVersion,&phClientHandle);
用WlanEnumInterfaces來枚舉interfaces到一個WLAN_INTERFACE_INFO_LIST結(jié)構(gòu)。如下:
WlanEnumInterfaces(phClientHandle,NULL,&wiiList);
然后wiiList->dwNumberOfItems的值就是無線網(wǎng)卡的數(shù)量。
VC6的時候沒有Wlanapi.h頭文件。可以直接LoadLibrary("wlanapi.dll"),然后GetProcAddress取得以上兩個函數(shù)指針。














#include <windows.h>
#include <stdio.h>
int main()
{
HKEY bKey,hKey;
LONG retVal;
DWORD dwBuf = 1;
DWORD dwLen;
char SubKey[] = "System\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}";
char SubKeyValueName[] = "MediaSubType";
bKey = HKEY_LOCAL_MACHINE;
retVal = RegOpenKeyEx(bKey,SubKey,0,KEY_ALL_ACCESS,&hKey);
if(retVal!=ERROR_SUCCESS)
{
return -1;
}
RegQueryValueEx( bKey, SubKeyValueName, 0, 0, (LPBYTE)&dwBuf, &dwLen );
if ( dwBuf == 1 )
printf( "普通網(wǎng)卡\n " );
if ( dwBuf == 2 )
printf( "無線網(wǎng)卡\n " );
return 0;
}
posted @ 2010-12-16 08:45 wrh 閱讀(2184) | 評論 (0)編輯 收藏

轉(zhuǎn)載文章一:http://www.cnblogs.com/shanhaobo/articles/1065380.html

[3D基礎(chǔ)]理解計算機3D圖形學(xué)中的坐標(biāo)系變換

     要談坐標(biāo)系變換,那么坐標(biāo)系有哪些呢?依次有:物體坐標(biāo)系,世界坐標(biāo)系,相機坐標(biāo)系,投影坐標(biāo)系以及屏幕坐標(biāo)系.我要討論的就是這些坐標(biāo)系間的轉(zhuǎn)換。
     這些坐標(biāo)系不是憑空而來,他們都是為了完成計算機3D圖形學(xué)最最最基本的目標(biāo)而出現(xiàn).
      計算機3D圖形學(xué)最最最基本的目標(biāo)就是:將構(gòu)建好的3D物體顯示在2D屏幕坐標(biāo)上.
      初看好像就是將最初的物體坐標(biāo)系轉(zhuǎn)換到屏幕坐標(biāo)系就可以了呀,為什么多出了世界坐標(biāo)系,相機坐標(biāo)系,投影坐標(biāo) 系。這是因為:在一個大世界里有多個物體,而每個物體都有自己的坐標(biāo)系,如何表述這些物體間相對的關(guān)系,這個多出了世界坐標(biāo)系;如果只需要看到這個世界其 中一部分,這里就多出了相機坐標(biāo)系;至于投影坐標(biāo)系那是因為直接將3D坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo)是非常復(fù)雜的(因為它們不僅維度不同,度量不同(屏幕坐標(biāo)一般都 是像素為單位,3D空間中我們可以現(xiàn)實世界的米,厘米為單位),XY的方向也不同,在2D空間時還要進(jìn)行坐標(biāo)系變換),所以先將3D坐標(biāo)降維到2D坐標(biāo), 然后2D坐標(biāo)轉(zhuǎn)換到屏幕坐標(biāo)。
理解3D圖形學(xué)的第一步:理解左手坐標(biāo)系與右手坐標(biāo)系
      為什么會有左手坐標(biāo)系與右手坐標(biāo)系之分?
      在3D空間(沒錯!就是3D)中,所有2D坐標(biāo)系是等價的(就是通過一系列的仿射變換,可以互相轉(zhuǎn)換)
      而3D坐標(biāo)系不是等價的,通過仿射變換,是無法將左手坐標(biāo)系轉(zhuǎn)換到右手坐標(biāo)系;也就是說,物體坐標(biāo)系用的就是左手坐標(biāo)系,世界坐標(biāo)系用的是右手 坐標(biāo)系,那么物體可能就是不會是我們所希望的樣子了,可能是倒立的,也可能是背對著我們的,所以我們要區(qū)分左手坐標(biāo)系與右手坐標(biāo)系。也許在4D空間,左右 手坐標(biāo)系就可以互相變換了吧。
      進(jìn)入正題吧:
     首先討論的是物體坐標(biāo)系->世界坐標(biāo)系
      前面說了為了描述多個物體間相對的關(guān)系,這里引進(jìn)了世界坐標(biāo)系,所以世界坐標(biāo)系是個參考坐標(biāo)系。
      這一步的目的將所有的物體的點都轉(zhuǎn)移到世界坐標(biāo)系,這里主要涉及的是旋轉(zhuǎn),縮放,平移等。
      不過我將詳細(xì)說明為何及如何用矩陣來描述這些變換。
      例:如果有兩個坐標(biāo)系C與C`, C`是C繞Z軸旋轉(zhuǎn)θ得到的。下面是各坐標(biāo)軸的變換:
             
     如果是C坐標(biāo)系的點P(x, y, z),而在C`的表示就是
   
     這時該如何建立矩陣呢? 答案就是區(qū)分你用的是行向量還是列向量.也許有人會問為什么不區(qū)分是左手坐標(biāo)系還是右手坐標(biāo)系呢?因為C可以變換到C`,那么他們一定是同在左手坐標(biāo)系或右手坐標(biāo)系,變換只能在可以互相轉(zhuǎn)換的坐標(biāo)系之間進(jìn)行。
      如果你用的是行向量:由于行向量只能左乘矩陣(注意乘與乘以的區(qū)別)
      所以矩陣形式應(yīng)該是這樣
    
     只有這樣,在左乘矩陣時才能得到上面P`的形式。
    
     如果你用的是列向量: 由于列向量只能右乘矩陣(注意乘與乘以的區(qū)別)
     所以矩陣形式應(yīng)該是這樣
    
     只有這樣,在右乘矩陣時才能得到上面P`的形式。
  
     至于如何旋轉(zhuǎn),縮放,平移我不在多說。
     …………………………………覺得自己好像跑題了.還好這兩個坐標(biāo)系變換很簡單。
     我們再討論世界坐標(biāo)系->相機坐標(biāo)系
     引進(jìn)相機的目的就是只需看到世界的一部分,而哪些是可以在相機里看到的,就需要進(jìn)行篩選。將物體轉(zhuǎn)換到相機坐標(biāo)系,這樣相機坐標(biāo)系進(jìn)行篩選時就會簡單很多。這里的重點是構(gòu)建相機坐標(biāo)系。
     物體坐標(biāo)系,世界坐標(biāo)系是美工在繪制時就定義好了的。而相機坐標(biāo)系是需要程序?qū)崟r構(gòu)建的。(當(dāng)然這是通常情況下,如果你要建立一個世界,這個世界都是圍繞 你轉(zhuǎn),要實時改變所有物體坐標(biāo)系,固定相機坐標(biāo)系(其實這時候相機坐標(biāo)系就是世界坐標(biāo)系),建立一個地心說的世界,我也沒辦法,你的思維也太不一樣了。)
     如何構(gòu)建相機坐標(biāo)系呢?首先我們要明確目標(biāo):我們是要構(gòu)建3D坐標(biāo)系(好像是廢話),三個坐標(biāo)軸要互相垂直(也好像是廢話).
      我們一般用UVN相機。例如:D3D的D3DXMatrixLookAtLH,D3DXMatrixLookAtRH,OGL的gluLookAt(右手坐標(biāo)系).
      如何建立呢UVN相機呢? 我們就要利用叉積這個工具了:兩個不平行,不重疊的向量的叉積可以得到與這兩個向量互相垂直的向量。
      如果有了相機的位置與目標(biāo)的位置那么我們可以確定一個Z軸(有人問為什么是Z軸,因為物體的遠(yuǎn)與近我們就習(xí)慣用Z值來表示的)。求Z軸時要注意 是左手坐標(biāo)系還是右手坐標(biāo)系,左右手坐標(biāo)系XY軸方向相同時,Z軸的方向相反。所以左手坐標(biāo)系是目標(biāo)位置減去相機位置,而右手坐標(biāo)系則是相機位置減去目標(biāo) 位置。記得normalize
     這是我們要得到X與Y軸了。如何求X,Y軸呢?
     一般方法是:
     1、選擇一個臨時Y軸,
     2、對臨時Y 與Z 軸進(jìn)行叉積求得一個X軸
     3、X軸再與Z軸進(jìn)行叉積,得到一個Y軸。
     有了XYZ就可以求出旋轉(zhuǎn)的相機矩陣了。
     如何選擇一個Y軸呢?大多數(shù)情況下是(0,1,0),但是如果是相機位置E與目標(biāo)位置T垂直,即(E-T=(0,+/-1,0)時),這時就不能用(0,1,0)了, 因為兩個平行向量的叉積是零向量,所以我們就要另選一個Y軸。
     但是我覺得我們可以改變方法。
      如果不能選Y軸,我們就選擇一個臨時X軸,這個臨時X軸就是(1,0,0)。
     然后再對臨時X軸與Z軸進(jìn)行叉積求得一個Y軸。
     最后Y軸再與Z軸進(jìn)行叉積,得到X軸。
      這樣可以得到XYZ軸。
      最后再根據(jù)行向量與列向量建立相機矩陣,再進(jìn)行平移。

     相機坐標(biāo)系->投影坐標(biāo)系.
     投影的目的就是:降維.
      兩種投影方式:正交投影與透視投影.
      在我們TEAM中易穎已經(jīng)寫了,我就不多說了,大家去看他的文章。

     投影坐標(biāo)系->屏幕坐標(biāo)系
      這是最簡單的。2D坐標(biāo)變換。也不多說。

轉(zhuǎn)載文章2:http://www.xingousi.com/computer/computergraphics.htm

計算機圖形學(xué)筆記(Part 1 ):計算機圖形學(xué)透視投影變換原理及一點和兩點透視

 

一、平行互分法

吳英凡所寫的《透視作圖的新方法——交點法體系》,其中談到的平行互分法,還是有道理的。

其實簡單點說,就是透視圖上的兩條“原來空間中的平行線”(在畫面上透視投影為相交于滅點),通過其中一條透視投影直線的端點畫另一條透視投影直線的平行線,必平行于畫面;這第三條線在畫面的透視投影的滅點必然在另一條透視投影線上。

 

 

 

二、透視投影變換學(xué)習(xí)總結(jié)

1、用多維數(shù)列表示低維空間坐標(biāo),加深理解齊次坐標(biāo)表示法。

    齊次坐標(biāo)表示法可以方便地運算,同時形狀不變。[x,y,z,0]表示一個無窮的點。

   

2、透視投影變換公式可以看成兩個矩陣的乘積,其中一個做透視變換,另外一個作正投影

   保留的z'值的確切含義:指的是在完全作完透視投影變換之前,僅作透視投影之后的一條線.

   它的幾何意義見李建平《計算機圖形學(xué)原理教程》第44頁。

3、左手和右手坐標(biāo)系的坐標(biāo)轉(zhuǎn)換

   “視點坐標(biāo)系與一般的物體所在的世界坐標(biāo)系不同,它遵循左手法則,即左手大拇指指向Z正軸,與之垂直的四個手指指向X正軸,四指彎曲90度的方向是Y正軸。而世界坐標(biāo)系遵循右手法則的。”

4、視點坐標(biāo)系的透視變換公式很重要!!王飛著計算機圖形學(xué)書65

5z'值的確切含義:指的是在完全作完透視投影變換之前,僅作透視投影之后的一條線

 

 

 

三、兩點透視的變換矩陣:

王飛編著《計算機圖形學(xué)基礎(chǔ)》的道理是:

從平面圖形的平移、旋轉(zhuǎn)、錯切開始推導(dǎo),兩點透視的變換矩陣可以看成是:

物體本身有一個物體坐標(biāo)系——xw,yw,zw,視點作為原點又構(gòu)成一個視點坐標(biāo)系——xeyeze,物體坐標(biāo)系z軸朝上,y軸朝向遠(yuǎn)處;而視點坐標(biāo)系y軸朝上,z軸朝向遠(yuǎn)處。

這樣,最終的二點透視狀態(tài)可以這樣取得,首先把物體的位置的物體坐標(biāo)系表示法轉(zhuǎn)化為視點坐標(biāo)系的表示法(第一個矩陣),然后圍繞視點坐標(biāo)系的y軸旋轉(zhuǎn)(第二個矩陣),然后在xyz方向上平移(第三個矩陣),最后做透視變換(第四個矩陣),它的原文是把平移放在第二步,我在平移之前轉(zhuǎn)動,目的是保證了物體旋轉(zhuǎn)的軸在離它不遠(yuǎn)的地方:

我使用的矩陣變換如下,原文是是把平移放在第二步:

[xw,yw,zw,1]* ***

 

最后所得結(jié)果是一個新的矩陣,

[xe ye ze 1]=[cos*xw-sin*yw+l   zw+m   2sin*xw+2cos*yw+2n-d   (sin*xw+cos*yw+n/d]

把最后一項變成1,可得

=[(cos*xw-sin*yw+l)*d/(sin*xw+cos*yw+n   (zw+m)*d/(sin*xw+cos*yw+n)   2sin*xw+2cos*yw+2n-d*d/(sin*xw+cos*yw+n)    1 ]


即:

Xe= (cos*xw-sin*yw+l)*d/(sin*xw+cos*yw+n)

Ye=(zw+m)*d/(sin*xw+cos*yw+n)

Ze=(2sin*xw+2cos*yw+2*n-d)*d/(sin*xw+cos*yw+n)

 

實際上我的delphi程序里面是這樣的:

xe:=trunc((cos(angle)*eee[ii][k].X-sin(angle)*eee[ii][k].Y+l)*d/(sin(angle)*eee[ii][k].X+cos(angle)*eee[ii][k].Y+n));

        ye:=trunc((hhh[ii][k]+m)*d/(sin(angle)*eee[ii][k].X+cos(angle)*eee[ii][k].Y+n)); //透視變換

        //ze可以考慮使用作為消隱

Ze:=trunc((2*sin(angle)*xw+2*cos(angle)*yw+2*n-d)*d/(sin(angle)*xw+cos(angle)*yw+n));

 

 

四、通過變換過的兩點透視的結(jié)果xe,yezw*,反求原來的物體坐標(biāo)xw,yw

即:xe,yezw已知,求出xw,yw

根據(jù):

Xe= (cos*xw-sin*yw+l)*d/(sin*xw+cos*yw+n)          1

Ye=(zw+m)*d/(sin*xw+cos*yw+n)                         2

Ze=2sin*xw+2cos*yw+2n-d*d/(sin*xw+cos*yw+n) 3

1)除以(2)得

Xe/Ye= (cos*xw-sin*yw+l)/ (zw+m)

(Xe*(zw+m))/Ye=cos*xw-sin*yw+l

(Xe*(zw+m))/(Ye* cos)=xw-tan*yw+l/cos

Xw=(Xe*(zw+m))/ (Ye* cos) - (ye*l)/(Ye* cos)+( sin*yw*ye)/ (Ye* cos)

 

Xw=(Xe*(zw+m)+ sin*yw*ye- ye*l)/ (Ye* cos)            (4)

 

由(2)得

Ye*(sin*xw+cos*yw+n)= (zw+m)*d

Ye*(sin*xw)+ye* cos*yw+n*ye=(zw+m)*d

把(4)代入上式得

Ye* sin*(Xe*(zw+m)+ sin*yw*ye- ye*l)/ (Ye* cos)+ye* cos*yw+n*ye=(zw+m)*d

約去ye,得

sin*(Xe*(zw+m)+ sin*yw*ye- ye*l)/ cos+ye* cos*yw+n*ye=(zw+m)*d

tan*(Xe*zw+xe*m+ sin*yw*ye- ye*l) +ye* cos*yw+n*ye=(zw+m)*d

tan*Xe*zw+xe*m *tan- ye*l*tan+ sin*tan*yw*ye+ye* cos*yw+n*ye=(zw+m)*d

(sin*tan*ye+ye* cos)*yw+ tan*Xe*zw+xe*m *tan- ye*l*tan+n*ye=(zw+m)*d

 

最后得

Yw=[(zw+m)*d- tan*Xe*zw- xe*m *tan+ ye*l*tan- n*ye]/ (sin*tan*ye+ye* cos) 5

而前面已經(jīng)得到

Xw=(Xe*(zw+m)+ sin*yw*ye- ye*l)/ (Ye* cos)            (4)

 

實際上相當(dāng)于opengl里面的逆變換,從鼠標(biāo)選中的屏幕位置來確定對應(yīng)的三維空間中位置,opengl使用gluUnProjectgluUnProject4來計算。

posted @ 2010-12-06 14:19 wrh 閱讀(1291) | 評論 (0)編輯 收藏
     摘要: 1. API之網(wǎng)絡(luò)函數(shù) WNetAddConnection 創(chuàng)建同一個網(wǎng)絡(luò)資源的永久性連接 WNetAddConnection2 創(chuàng)建同一個網(wǎng)絡(luò)資源的連接 WNetAddConnection3 創(chuàng)建同一個網(wǎng)絡(luò)資源的連接 WNetCancelConnection 結(jié)束一個網(wǎng)絡(luò)連接 WNetCancelConnection2 結(jié)束一個網(wǎng)絡(luò)連接 WNetCloseEnum 結(jié)束一次枚舉操作 ...  閱讀全文
posted @ 2010-12-02 09:20 wrh 閱讀(1942) | 評論 (0)編輯 收藏
     摘要: //本機網(wǎng)絡(luò)連接類型(成功)   #define  NET_TYPE_RAS_DIAL_UP_CONNECT_NET           0x01    //上網(wǎng)類型:采用RAS撥號連接上網(wǎng) ...  閱讀全文
posted @ 2010-12-02 09:07 wrh 閱讀(9515) | 評論 (0)編輯 收藏
和所有初學(xué)者一樣,剛開始接觸新的東西,總想把畫面做的漂亮些,可是在vc中很難做到,比如對話框中按鈕等控件的字體設(shè)置,就頗費了我一番功夫。
    一。做成一個函數(shù),改變字體大小,方法如下:
      1。在最開頭聲明一個全局的字體指針 CFont *my_font=new CFont();//注意初始化,不能為空
      2。在需要改變字體的地方調(diào)用函數(shù):
          set_font(60,my_font,"隸書"); //字體大小、指針、名稱
          GetDlgItem(IDC_anniu)->SetFont(my_font);//改變字體
      3。對與不同的字體,你需要設(shè)置不同的字體指針就可以了。
      4。注意在退出時要刪除字體,否則多次調(diào)用出現(xiàn)問題
       BOOL CMyDlg::DestroyWindow()
      {
       if (my_font)   my_font->DeleteObject();
       return CDialog::DestroyWindow();
      }
      5。 以下是函設(shè)置字體函數(shù)的詳細(xì)內(nèi)容:
void set_font(int height,CFont *font,char *name)
{
// font=new CFont();//不在此,要在外部初始化,否則找不到指針
     LOGFONT lf;
   lf.lfHeight=20;          lf.lfWidth= 0;
lf.lfEscapement=0;    lf.lfOrientation= 0;
lf.lfWeight= 760;      lf.lfItalic= 0;
lf.lfUnderline =0;      lf.lfStrikeOut =0;
lf.lfCharSet =134; lf.lfOutPrecision =3;
lf.lfClipPrecision =2; lf.lfQuality= 1;
lf.lfPitchAndFamily =2; lstrcpy(lf.lfFaceName, "宋體");
lf.lfOutPrecision =OUT_TT_ONLY_PRECIS;//OUT_TT_PRECIS;
   
lf.lfHeight= height;   //字體大小
     lstrcpy(lf.lfFaceName, name);//名稱
    if (font!=NULL)
    {
font->DeleteObject();
font->CreateFontIndirect(&lf);
    }
}
  
#define say(ch) AfxMessageBox(ch)//自己使用的提示函數(shù)
#define bt(ch)   SetWindowText(ch)//自己使用的提示函數(shù)
  
二。改變字體顏色,要加入系統(tǒng)函數(shù)
HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
//    return hbr;
    switch(nCtlColor)
{
case CTLCOLOR_STATIC://靜態(tài)文本
   TCHAR lpszClassName[255];
   GetClassName(pWnd->m_hWnd, lpszClassName, 255);
   if(_tcscmp(lpszClassName, TRACKBAR_CLASS) == 0)//類名是拉動條
    return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
   else if (IDC_tishi==pWnd->GetDlgCtrlID())//指定的控件ID提示
    {
     pDC ->SetTextColor(RGB(255,100,100));//RGB(100,255,100)
     return hbr;
    }
   else
    {
     pWnd->GetWindowText(ch,40);
     if (   strcmp(ch,"測試數(shù)據(jù)")==0 )//指定的標(biāo)題
     {
      pDC ->SetTextColor(RGB(255,0,200));
         return hbr;  
     }
     pDC->SetBkColor(RGB(255,255,255));
     return hbr;//(HBRUSH) GetStockObject(HOLLOW_BRUSH);
    }
   }
   break;
     case CTLCOLOR_BTN://按鈕,好象不行
   // pDC ->SetBkMode(OPAQUE);//背景不透明
    // pDC->SetBkMode(TRANSPARENT);//背景透明
//   say("button");
        CString str;
//owen draw //注意,右擊按鈕屬性改為自繪式
     pWnd->GetWindowText(str); //得到標(biāo)題內(nèi)容
     RECT rect;
      pWnd->GetClientRect(&rect);//得到矩形范圍大小
   pDC->SelectStockObject(BLACK_PEN);
   pDC->Rectangle(&rect);//黑筆畫外邊矩形
   rect.left+=2;rect.top+=2;
   rect.right-=2 ;rect.bottom-=2;
   pDC->SelectStockObject(WHITE_PEN);
   pDC->Rectangle(&rect);//白筆畫內(nèi)矩形
   pDC->SelectObject(font);//選擇字體,大小
   pDC->SetTextColor(RGB(0,255,0)); //字體得前景顏色
   pDC->SetBkColor(RGB(255,0,255)); //字體的背景顏色
   pDC->DrawText(str, &rect, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
   return (HBRUSH) GetStockObject(HOLLOW_BRUSH);
        break;
     case CTLCOLOR_EDIT://
編輯框
        pDC ->SetTextColor(RGB(255,0,0));//文本顏色
        pDC ->SetBkColor(RGB(255,255,255));//文本背景
        break;
     case CTLCOLOR_LISTBOX://
列表框
    // pDC ->SetTextColor(RGB(255,255,0));
    // pDC ->SetBkColor(RGB(160,60,0));
        break;
     }
// TODO: Return a different brush if the default is not desired
return hbr;
}
posted @ 2010-12-02 08:54 wrh 閱讀(2732) | 評論 (0)編輯 收藏

2008-06-23 星期一 天氣  

      很久沒有來這里寫東西了,感覺真有點對不起這個空間. 
 過年到現(xiàn)在一直都忙于工作.(項目一個接一個.報告一個接一個) 
驅(qū)動開發(fā)我關(guān)注很久了.就是沒有實際行動.終于有一天不知道怎么了下定了決心搞了. 
首先要搞的是編譯和編輯環(huán)境,個人感覺網(wǎng)上有很多DDK Visual Studio6的配置很多都是有問題的,而且都是幾年前寫的.不知道是我理解能力有問題還是作者表達(dá)能力有問題老是弄不好.最后弄雖然弄好也是轉(zhuǎn)了一個大圈.但是用起來實在是不敢恭謹(jǐn).也許是我用慣了delphi vs2005的緣故.vs2005的代碼編輯和智能排版功能可以說是very Good ! 最后我還是決定把ddkvs2005給掛上關(guān)系.花了我一個上午的時間也弄出來了.用起來比vs6.0爽了很多.效果也達(dá)到了之前設(shè)想的.我寫這些出來是為了減少步我后塵的同志們對驅(qū)動的恐懼.

步驟:
1.首先前期準(zhǔn)備: 安裝xp ddk  vs2005 (vs2005只要安裝c/c++就可以了) 安裝的步驟我就不在這里說了.

2.準(zhǔn)備一個驅(qū)動源代碼(ddk內(nèi)的例子也可以)

3.vs2005建立一個makeFile 工程.

4.把源碼拷貝倒vs2005目錄內(nèi)(包括*.c , *.h,還有source  makefile)

5.vs2005工程目錄建立一個MakeDriver.bat 文件里面內(nèi)容是:

@echo off

if "%1"=="" goto usage1
if "%3"=="" goto usage2
if not exist %1\bin\setenv.bat goto usage3

echo params1: %1 
echo params2: %2
echo params3: %3


echo call %1\BIN\setenv %1 %3
call %1\BIN\setenv %1 %3

echo cd /d %2
cd /d %2


build
goto ok

:usage1
echo Error: the first parameter is NULL!
goto exit

:usage2
echo Error: the third parameter is NULL!
goto exit

:usage3
echo Error: %1\bin\setenv.bat not exist!
goto exit

:ok
echo MakeDriver %1 %2 %3
:exit

5. 設(shè)置 vs2005 工程的屬性
    編譯分 debug release 兩個版本

NMke 設(shè)置里面設(shè)置 ( 我用的是 vs2005 繁體版






























releasee 版本.只要將 建置命令列 內(nèi)容改成 MakeDriver %DDKROOT% $(ProjectDir) fre 就可以了.


我的 ddk 是安裝在 c .IntelliSense 是為了能在編輯代碼的時候彈出輸入的列表 . 比如結(jié)構(gòu)體內(nèi)的成員等等


建置命令列 : 是調(diào)用 MakeDriver.bat 文件編譯源代碼 .


如果加上 vss 代碼管理 . 一個驅(qū)動代碼工程管理就算完善了 .

寫到這里了 .

順便提下要了解 MakeDriver.bak 內(nèi)的作用就要了解一些批處理的 dos 命令 . 上網(wǎng)找吧 . 網(wǎng)上什么都有關(guān)鍵是看你怎么找 .

posted @ 2010-12-01 13:12 wrh 閱讀(799) | 評論 (0)編輯 收藏

 http://harborwan.blog.sohu.com/39762230.html

通常驅(qū)動程序的調(diào)試都是用ddk在cmd中完成的。這部分我暫時略過。下面先介紹如何設(shè)置vc++6.0在Visual Studio 6.0集成環(huán)境中開發(fā)設(shè)備驅(qū)動程序的方法。

在Windows上,Windows DDK提供的開發(fā)環(huán)境是基于命令行的,操作起來極為不便,而Visual Studio 6.0給我們提供了非常友好易用的集成環(huán)境,讓我們有如虎添翼之感。 
  那么,能否利用Visual Studio的集成環(huán)境來開發(fā)驅(qū)動程序呢?答案是可以的。通過對Visual Studio集成環(huán)境的簡單設(shè)置,創(chuàng)建好自己的驅(qū)動開發(fā)集成環(huán)境就可以了。

1,

第一:安裝Vc++6.0,我裝的是英文版,中文版應(yīng)該也可以,不過我沒試。

第二:安裝winXP DDK,注意,安裝目錄中間不能有空格,比如D:\Program Files不行,

我直接裝在了D盤,裝完后設(shè)置環(huán)境變量DDKROOT為安裝目錄D:\WINDDK\2505。

2,創(chuàng)建一個目錄,作為開發(fā)目錄,我是利用<<PCI設(shè)備開發(fā)寶典>>的光盤中的工程文件PCI9052Demo,直接考到E盤,所以,工作目錄下是E:\PCI9052Demo

3,工作目錄下創(chuàng)建一個批處理文件MakeDrvr.bat,內(nèi)容如下:

@echo off
if "%1"=="" goto usage
if "%3"=="" goto usage
if not exist %1\bin\setenv.bat goto usage
call %1\bin\setenv %1 %4
%2
cd %3
build -b -w %5 %6 %7 %8 %9
goto exit

:usage
echo usage   MakeDrvr DDK_dir Driver_Drive Driver_Dir free/checked [build_options]
echo eg      MakeDrvr %%DDKROOT%% F: %%WDMWorkshop%% free -cef
:exit

解釋以下:

1% 是DDK_dir,也就是ddk的安裝目錄

2% 是Driver_Drive,是你工作目錄所在的盤符,這里是E:

3% 是Driver_Dir,是你工作目錄的路徑,這里是E:\PCI9052Demo

4% 是編譯模式,checked表示調(diào)試模式,free表示發(fā)行模式,這里是出問題的地方,后面再說。

該批處理首先對傳遞的參數(shù)作一些檢查,然后調(diào)用ddk的setenv命令設(shè)置環(huán)境變量,然后改變目錄為源程序所在驅(qū)動器和目錄,并最后調(diào)用build,-b保證顯示完全的錯誤信息,-w保證在屏幕上輸出警告,在vc ide里的output窗口中可以看到這些錯誤和警告。

4,建立一個空白工程
 選File的new菜單項,然后選project欄的makefile,然后輸入路徑,一路next下去即可,visual studio提供兩種配置win32 debug和win32 release. 按照cant的《windows wdm 設(shè)備驅(qū)動程序開發(fā)指南》方法,可以刪除掉,添加Win32 Checked和 Win32 Free

5,VC的Project->settings里面改變設(shè)置

修改這兩種配置
 =============================================================
 Free
 =============================================================
 build command line:
 e:\PCI9052Demo\MakeDrvr %DDKROOT% e: e:\PCI9052Demo free
 
 rebuild all opinions:
 -nmake /a

 output filename:
 PCI9052Demo.sys

 browse info file name:
 objfre\i386\PCI9052Demo.bsc


 =============================================================
 Checked
 =============================================================
 build command line:
 e:\PCI9052Demo\MakeDrvr %DDKROOT% e: e:\PCI9052Demo checked
 
 rebuild all opinions:
 -nmake /a

 output filename:
 PCI9052Demo.sys

 browse info file name:
 objfre\i386\PCI9052Demo.bsc

6.添加源文件到工程
  可以新建,也可

posted @ 2010-12-01 13:11 wrh 閱讀(279) | 評論 (0)編輯 收藏
僅列出標(biāo)題
共25頁: 1 2 3 4 5 6 7 8 9 Last 

導(dǎo)航

<2010年11月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

統(tǒng)計

常用鏈接

留言簿(19)

隨筆檔案

文章檔案

收藏夾

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一卡久久| 一区二区不卡在线视频 午夜欧美不卡在 | 欧美日韩高清免费| 欧美日本韩国| 韩国美女久久| 女人色偷偷aa久久天堂| 一区二区三区欧美亚洲| 女主播福利一区| 久久色在线播放| 亚洲欧美国产va在线影院| 影音先锋久久久| 国产精品久久久久久久浪潮网站| 这里只有精品视频在线| 亚洲一区在线观看免费观看电影高清| 国产精品综合| 欧美午夜精品久久久久免费视| 久久综合综合久久综合| 欧美激情一区二区久久久| 久久动漫亚洲| aa级大片欧美| 亚洲精品在线一区二区| 136国产福利精品导航网址应用| 欧美在线播放一区| 亚洲高清视频一区| 亚洲第一页中文字幕| 国产欧美一区二区色老头| 欧美日韩亚洲国产精品| 日韩一区二区免费高清| 免播放器亚洲| 久久高清一区| 欧美亚洲视频| 欧美在线不卡视频| 一个人看的www久久| 国产在线麻豆精品观看| 日韩视频不卡| 久久亚洲精品欧美| 中国成人在线视频| 欧美国产一区视频在线观看| 国产精品自拍在线| 亚洲视频在线观看三级| 欧美大片免费| 久久久国产精品一区二区三区| 欧美日韩亚洲成人| 亚洲黄一区二区| 久久亚洲综合色| 性欧美超级视频| 国产精品久久久久影院亚瑟| 日韩视频精品| 91久久精品一区二区别| 久久日韩精品| 亚洲国产精品va在线看黑人动漫| 亚洲在线中文字幕| 麻豆精品一区二区av白丝在线| 欧美电影在线| 亚洲精品在线一区二区| 欧美在线日韩在线| 亚洲美女一区| 欧美激情亚洲精品| 亚洲高清av| 美日韩精品免费观看视频| 亚洲一区二区三区三| 欧美日韩视频一区二区| 亚洲免费成人av| 欧美激情性爽国产精品17p| 欧美专区日韩视频| 国产婷婷色一区二区三区| 校园春色综合网| 亚洲欧美成人网| 国产欧美日韩亚洲精品| 亚洲在线日韩| 亚洲影视综合| 国产日韩欧美a| 午夜精品久久久久久99热| 日韩一区二区电影网| 欧美日韩1区2区| 亚洲一区二区不卡免费| 99这里只有精品| 欧美日韩亚洲一区二区三区在线 | 午夜久久久久久| 在线视频日本亚洲性| 国产精品v欧美精品v日韩精品| 一区二区三区你懂的| 在线视频精品一| 欧美国产综合一区二区| 国产精品青草久久| 亚洲欧美精品在线| 久久久久一区二区三区四区| 亚洲欧美在线播放| 一区二区视频免费完整版观看| 欧美国产成人精品| 欧美高清自拍一区| 99精品欧美一区二区蜜桃免费| 久久国产精品久久久久久电车| 欧美一区二区三区精品电影| 樱桃国产成人精品视频| 亚洲激情视频在线播放| 久久国产精品久久久久久久久久 | 国产区精品视频| 久久性天堂网| 欧美日韩一本到| 亚洲午夜一区二区三区| 欧美三区在线观看| 久久久www免费人成黑人精品 | 欧美一区二区三区免费大片| 亚洲黄色免费| 亚洲欧洲一区二区在线播放| 日韩一区二区电影网| 国产精品亚洲аv天堂网| 久久天堂精品| 欧美日本三级| 蜜桃久久精品一区二区| 欧美日韩精品一本二本三本| 欧美一区二区三区免费视频| 欧美激情精品久久久久久大尺度 | 久久在线免费| 欧美日韩一区二| 亚洲国产欧美久久| 国产乱码精品| 日韩视频二区| 亚洲精品免费在线| 久久国产欧美| 亚洲欧美中文字幕| 欧美精品一卡| 欧美成人午夜免费视在线看片| 国产精品毛片| 亚洲免费黄色| 亚洲国产精品久久久久秋霞不卡 | av不卡在线| 夜夜狂射影院欧美极品| 久久人人97超碰国产公开结果| 午夜日韩激情| 欧美亚男人的天堂| 欧美一级黄色录像| 欧美日韩免费一区二区三区视频| 男同欧美伦乱| 国内视频一区| 久久精品国产96久久久香蕉| 亚洲欧美资源在线| 国产精品丝袜91| 一区二区三区四区精品| 一本久久知道综合久久| 欧美激情亚洲综合一区| 欧美激情精品久久久六区热门| 精品51国产黑色丝袜高跟鞋| 久久本道综合色狠狠五月| 蜜臀va亚洲va欧美va天堂| 久热这里只精品99re8久| 国产视频一区欧美| 欧美一区精品| 免费成人高清| 亚洲激情在线观看| 欧美激情免费在线| 亚洲黄色免费网站| 日韩写真在线| 国产精品电影观看| 午夜精品久久久久久久男人的天堂| 亚洲女ⅴideoshd黑人| 国产精品久久久久久久久免费樱桃| 一区二区三区产品免费精品久久75 | 亚洲高清免费在线| 久久久久久亚洲精品中文字幕| 在线亚洲精品| 亚洲大片av| 国产精品一区二区三区四区 | 欧美一区二区私人影院日本| 国产精品v欧美精品v日韩精品| 亚洲欧美国产另类| 开元免费观看欧美电视剧网站| 影音欧美亚洲| 欧美日本国产一区| 欧美亚洲在线观看| 欧美国产精品va在线观看| 最新国产成人av网站网址麻豆| 农村妇女精品| 亚洲午夜电影在线观看| 久久偷看各类wc女厕嘘嘘偷窃| 亚洲高清视频在线| 欧美日韩在线观看视频| 欧美一区二区三区在线观看视频| 美女国产一区| 一区二区不卡在线视频 午夜欧美不卡'| 亚洲精品一二| 欧美一级在线视频| 在线观看日韩av电影| 欧美精品在线免费| 午夜精品成人在线| 亚洲高清自拍| 性视频1819p久久| 亚洲日本成人| 国产日本亚洲高清| 欧美激情久久久久久| 亚洲欧美日韩中文在线制服| 亚洲大片精品永久免费| 欧美一区二区精品久久911| 亚洲精品乱码视频| 蜜臀99久久精品久久久久久软件 | 亚洲美女av黄| 亚洲国产天堂久久综合网| 欧美一区日韩一区| 91久久久久久久久|