public void RasDial(SERVICE_CLASSES_UUID16 scuServiceClass, string sBluetoothAddress, string sPhoneNumber, string sUserName, string sPassword, int iChannel)
{
//step 1: maybe keep a list to check if this connection is already active
//step 2: createBluetoothDeviceRegistryEntry
//> Purpose: create the registry entry for a bluetooth RAS device
//> ---------------------------------------------------------------------------
#if UseCOM1
int iPort = 1;
#else
int iPort = 2;
#endif
string m_strDeviceFriendlyName = GetRegDeviceName(scuServiceClass) + "(" + sBluetoothAddress + ")";
string m_strEntryName = "BSP"+ iPort.ToString();
RegistryKey rk = Registry.LocalMachine;
using (RegistryKey rk1 = rk.CreateSubKey("\\Software\\Microsoft\\bluetooth\\device\\" + GetRegDeviceName(scuServiceClass) + "\\" + GetUnformattedBluetoothAddress(sBluetoothAddress)))
{
rk1.SetValue("handle", 0 );
rk1.SetValue("encrypt", 1);
rk1.SetValue("auth", 1);
rk1.SetValue("mtu", scuServiceClass != SERVICE_CLASSES_UUID16.PANU ? 2048 : 1024);
rk1.SetValue("hid_subclass", 0);
rk1.SetValue("channel", scuServiceClass != SERVICE_CLASSES_UUID16.PANU ? iChannel : 0); //need channel number from serial port connection
rk1.SetValue("port_name", "BSP"+ iPort.ToString());
rk1.SetValue("service_id", GetServiceClassString(scuServiceClass));
rk1.SetValue("name", m_strDeviceFriendlyName);
rk1.Close();
}
//step 3: createBluetoothDevicePortEntry
//> Purpose: the bluetooth port entry for the entry created in
//> createBluetoothDeviceRegistryEntry
//> ---------------------------------------------------------------------------
using (RegistryKey rk1 = rk.CreateSubKey("\\Software\\Microsoft\\bluetooth\\device\\ports\\" + m_strDeviceFriendlyName))
{
rk1.SetValue("context", 0);
rk1.SetValue("index", iPort);
rk1.SetValue("prefix", "BSP");
rk1.SetValue("dll", "btd.dll");
//Part2 of //step 5: enableBluetoothModem
PORTEMUPortParams pp = new PORTEMUPortParams();
byte[] bA = new byte[8];
if(GetBinaryBluetoothAddress(sBluetoothAddress, ref bA))
pp.device = System.BitConverter.ToInt64(bA, 0); //int address of bluetooth
else
pp.device = 0; //int address of bluetooth
pp.channel = iChannel;
pp.imtu = 0x00000800;
////
//// RFCOMM Apis
////
//#define RFCOMM_PORT_FLAGS_REMOTE_DCB 0x00000001
//#define RFCOMM_PORT_FLAGS_KEEP_DCD 0x00000002
//#define RFCOMM_PORT_FLAGS_AUTHENTICATE 0x00000004
//#define RFCOMM_PORT_FLAGS_ENCRYPT 0x00000008
pp.uiportflags |= 0x00000004; //RFCOMM_PORT_FLAGS_AUTHENTICATE
pp.uiportflags |= 0x00000008; //RFCOMM_PORT_FLAGS_ENCRYPT
IntPtr ipTmp = LocalAlloc(0x40, (uint)Marshal.SizeOf(pp));
Marshal.StructureToPtr(pp, ipTmp, false); //Troubleshooting Exceptions: System.NotSupportedException:have to change PORTEMUPortParams to simple one
rk1.SetValue("context", ipTmp.ToInt32()); //32 or 64..WORD
rk1.Close();
}
//step 4: createBluetoothDevicePortUnimodemEntry
//> Purpose: the bluetooth port unimodem entry for the entry created in
//> createBluetoothDevicePortEntry
//> ---------------------------------------------------------------------------
using (RegistryKey rk1 = rk.CreateSubKey("\\Software\\Microsoft\\bluetooth\\device\\ports\\" + m_strDeviceFriendlyName + "\\unimodem"))
{
rk1.SetValue("devicetype", 0);
rk1.SetValue("tsp", "unimodem.dll");
rk1.SetValue("devicetype", m_strDeviceFriendlyName); // //Part 1 of step 5: enableBluetoothModem
rk1.SetValue("friendlyname", scuServiceClass == SERVICE_CLASSES_UUID16.LANAccessUsingPPP ? 0 : 1);
rk1.Close();
}
//step 5: enableBluetoothModem
////> ---------------------------------------------------------------------------
////> Purpose: activate a pre-registered Bluetooth modem
////> ---------------------------------------------------------------------------
IntPtr ipReturn = ActivateDevice("software\\microsoft\\bluetooth\\device\\ports\\" + m_strDeviceFriendlyName, 0);
if (ipReturn.ToInt32() != -1)
{
//registr
using (RegistryKey rk1 = rk.CreateSubKey("software\\microsoft\\bluetooth\\device\\" + GetServiceClassString(scuServiceClass) + "\\" + GetUnformattedBluetoothAddress(sBluetoothAddress)))
//using (RegistryKey rk1 = rk.OpenSubKey("software\\microsoft\\bluetooth\\device\\" + GetServiceClassString(scuServiceClass) + "\\" + GetUnformattedBluetoothAddress(sBluetoothAddress), true))
{
//rk1.SetValue("handle", Convert.ToInt32(ipReturn));
rk1.SetValue("handle", ipReturn.ToInt32());
rk1.SetValue("active", 1);
// Already setup earlier
//rk1.SetValue("handle", 0);
rk1.SetValue("encrypt", 1);
rk1.SetValue("auth", 1);
rk1.SetValue("mtu", scuServiceClass != SERVICE_CLASSES_UUID16.PANU ? 2048 : 1024);
rk1.SetValue("hid_subclass", 0);
rk1.SetValue("channel", scuServiceClass != SERVICE_CLASSES_UUID16.PANU ? iChannel : 0); //need channel number from serial port connection
rk1.SetValue("port_name", "BSP" + iPort.ToString());
rk1.SetValue("service_id", GetServiceClassString(scuServiceClass));
rk1.SetValue("name", m_strDeviceFriendlyName);
rk1.Close();
}
}
else
{
MessageBox.Show("ActivateDevice failed!");
}
//step 6: if all above good: createRasPhoneBookEntry
RASDEVINFO[] rdiRets = new RASDEVINFO[1];
uint intRet = 0;
int lpcb = 0;
int lpcDevices = 0;
IntPtr devinfo = IntPtr.Zero;
int iFoundIndex = -1;
intRet = RasConnection.RasEnumDevices(IntPtr.Zero, ref lpcb, ref lpcDevices);
devinfo = Marshal.AllocHGlobal(lpcb);
rdiRets[0] = new RASDEVINFO();
rdiRets[0].dwSize = Marshal.SizeOf(typeof(RASDEVINFO));
Marshal.WriteInt32(devinfo, Marshal.SizeOf(rdiRets[0]));
intRet = RasConnection.RasEnumDevices(devinfo, ref lpcb, ref lpcDevices);
if (intRet == 0)
{
rdiRets = new RASDEVINFO[lpcDevices];
for (int i = 0; i < devinfo =" (IntPtr)(devinfo.ToInt32()" szdevicename ="="" ifoundindex =" i;" rasconnection =" new" szlocalphonenumber =" sPhoneNumber;" szdevicetype =" (sPhoneNumber" szdevicename =" m_strDeviceFriendlyName;" localrasconnection =" new" dwsize =" Marshal.SizeOf(typeof(RASENTRY));" bsp =" new" dwsize =" dwSize;" temp =" 512;" dwgetentry =" 0;" dwgetentry =" RasConnection.RasGetEntryProperties(">= 1)
{
MessageBox.Show("RasDial:Unable to retrieve information:" + dwGetEntry.ToString()); //passed after readjust struc
//return;
}else
{
//#define RASEO_DialAsLocalCall 0x00020000
localRasConnection.dwfOptions |= 0x00020000;
//#define RASEO_UseCountryAndAreaCodes 0x00000001
localRasConnection.dwfOptions &= ~(0x00000001);
//#define RASEO_SpecificIpAddr 0x00000002
localRasConnection.dwfOptions &= ~(0x00000002);
//#define RASEO_SpecificNameServers 0x00000004
localRasConnection.dwfOptions &= ~(0x00000004);
//#define RASEO_SwCompression 0x00000200
localRasConnection.dwfOptions &= ~(0x00000200);
//#define RASEO_IpHeaderCompression 0x00000008
localRasConnection.dwfOptions &= ~(0x00000008);
localRasConnection.dwCountryCode = 1;
//#define RASNP_Ip 0x00000004 // Negotiate TCP/IP
localRasConnection.dwfNetProtocols = 0x00000004;
//#define RASFP_Ppp 0x00000001 // Point-to-Point Protocol (PPP)
localRasConnection.dwFramingProtocol = 0x00000001;
localRasConnection.szDeviceType = (sPhoneNumber != "" ? "modem" : "direct");
localRasConnection.szDeviceName = m_strDeviceFriendlyName;
localRasConnection.szAreaCode = "";
localRasConnection.szLocalPhoneNumber = sPhoneNumber;
dwGetEntry = RasConnection.RasSetEntryProperties(null, m_strEntryName, ref localRasConnection, dwSize, null, 0);
if (dwGetEntry >= 1)
{
MessageBox.Show("RasDial:Unable to RasSetEntryProperties:" + dwGetEntry.ToString()); //621;passed after change first parameter from "" to null
//return;
}else
{
SetDialingParameters("0","Work","G","G","G","1","","0","0");
RASDIALPARAMS RasDialParams;
RasDialParams = new RASDIALPARAMS();
RasDialParams.dwSize = (int)Marshal.SizeOf(typeof(RASDIALPARAMS));
RasDialParams.szEntryName = m_strEntryName;
RasDialParams.szPhoneNumber = sPhoneNumber;
RasDialParams.szUserName = sUserName ;
RasDialParams.szPassword = sPassword;
dwGetEntry = RasConnection.RasSetEntryDialParams(null, ref RasDialParams, false);
IntPtr m_hRasConnection = IntPtr.Zero;
if (dwGetEntry >= 1)
{
MessageBox.Show("RasDial:Unable to RasSetEntryDialParams:" + dwGetEntry.ToString()); //610:passed after change first parameter from "" to null
//return;
}
dwGetEntry = RasConnection.RasDial(IntPtr.Zero, IntPtr.Zero, ref RasDialParams, 0, IntPtr.Zero, ref m_hRasConnection);
if (dwGetEntry >= 1)
{
MessageBox.Show("RasDial:Unable to RasDial:" + dwGetEntry.ToString()); //608:ERROR_DEVICE_DOES_NOT_EXIS //http://msdn.microsoft.com/en-us/library/bb530704(VS.85).aspx
//return;
}
}
}
}
}
}
private void SetDialingParameters(string KeyName, string Location, string LocalCalls,
string LongDistanceCalls, string InternationalCalls,
string AreaCode, string DisableCallWaitingSequence,
string CountryCode, string ToneOrPulse)
{
//C++ way
//string ConfigurationString = Location + "\0" + LocalCalls + "\0" + LongDistanceCalls + "\0" +
// InternationalCalls + "\0" + AreaCode + "\0" + DisableCallWaitingSequence + "\0" +
// CountryCode + "\0" + ToneOrPulse + "\0";
//C# The way to create REG_MULTI_SZ
string[] ConfigurationString = new string[8];
ConfigurationString[0] = Location;
ConfigurationString[1] = LocalCalls;
ConfigurationString[2] = LongDistanceCalls;
ConfigurationString[3] = InternationalCalls;
ConfigurationString[4] = AreaCode;
ConfigurationString[5] = DisableCallWaitingSequence;
ConfigurationString[6] = CountryCode;
ConfigurationString[7] = ToneOrPulse;
RegistryKey rk = Registry.CurrentUser;
using (RegistryKey rk1 = rk.CreateSubKey("ControlPanel\\Dial\\Locations"))
{
rk1.SetValue(KeyName, ConfigurationString);
rk1.Close();
}
}
private bool GetBinaryBluetoothAddress(string sBluetoothAddress, ref byte[] bBTAddress)
{
try
{
//00:03:c9:56:0c:EE
string[] sTmp = sBluetoothAddress.Split(':');
bBTAddress[0] = Convert.ToByte(sTmp[5], 16);
bBTAddress[1] = Convert.ToByte(sTmp[4], 16);
bBTAddress[2] = Convert.ToByte(sTmp[3], 16);
bBTAddress[3] = Convert.ToByte(sTmp[2], 16);
bBTAddress[4] = Convert.ToByte(sTmp[1], 16);
bBTAddress[5] = Convert.ToByte(sTmp[0], 16);
bBTAddress[6] = 0;
bBTAddress[7] = 0;
return true;
}
catch
{
return false;
}
}
private string GetUnformattedBluetoothAddress(string sBluetoothAddress)
{
//00:03:c9:56:0c:EE
string[] sTmp = sBluetoothAddress.Split(':');
string sUnformattedBTAddress = sTmp[5] + sTmp[4]+ sTmp[3] + sTmp[2] + sTmp[1] + sTmp[0] + "0000";
return sUnformattedBTAddress;
}
private RASDEVINFO[] getDevices()
{
RASDEVINFO[] rdiRets = new RASDEVINFO[1];
uint intRet = 0;
int lpcb = 0;
int lpcDevices = 0;
IntPtr devinfo = IntPtr.Zero;
intRet = RasConnection.RasEnumDevices(IntPtr.Zero, ref lpcb, ref lpcDevices);
devinfo = Marshal.AllocHGlobal(lpcb);
rdiRets[0] = new RASDEVINFO();
rdiRets[0].dwSize = Marshal.SizeOf(typeof(RASDEVINFO));
Marshal.WriteInt32(devinfo, Marshal.SizeOf(rdiRets[0]));
intRet = RasConnection.RasEnumDevices(devinfo, ref lpcb, ref lpcDevices);
if (intRet == 0)
{
rdiRets = new RASDEVINFO[lpcDevices];
for (int i = 0; i < lpcDevices; i++)
{
rdiRets[i] = new RASDEVINFO();
Marshal.PtrToStructure(devinfo, rdiRets[i]);
devinfo = (IntPtr)(devinfo.ToInt32() + Marshal.SizeOf(rdiRets[i]));
}
}
return rdiRets;
}
Thursday, January 29, 2009
Tuesday, January 27, 2009
Storage: MAP in C++ and List in C# (2)
MAP in C++ and List in C#
=====================
(2) MAP in C++=====================
In C++, we can use MAP to do similar thing as List in C#.
-------------------BTMap.h----
#include "BluetoothDevice.h"
#include map
using namespace std;
typedef struct
{
TCHAR tcDeviceName[100];
TCHAR tcAddress[100];
}BLUETOOTHDEVICE;
typedef map
typedef BLUETOOTHDEVICEMAP::iterator BLUETOOTHDEVICEITERATOR;
typedef pair
class BluetoothDeviceMap : public BLUETOOTHDEVICEMAP
{
private:
CRITICAL_SECTION m_CriticalSection;;
bool m_bIsDirty;
private:
BluetoothDevice *findBluetoothDevice(CString bluetoothAddress,int &iIndex);
void removeBluetoothDevice(int iIndex);
void removeBluetoothDevice(
public:
BluetoothDeviceMap(void);
virtual ~BluetoothDeviceMap(void);
int GetDeviceIndex(BluetoothDevice *pBluetoothDevice);
bool IsDevicePaired(DWORD dwIndex);
void SetDirtyBit() {m_bIsDirty = true;};
void RemoveBluetoothDevice(int iIndex);
void RemoveBluetoothDevice(
void RemoveBluetoothDevice(LPTSTR bluetoothAddress);
void flush();
void Flush();
BluetoothDevice *findBluetoothDevice(LPTSTR bluetoothAddress,int &iIndex);
BluetoothDevice *AddBluetoothDevice(
BluetoothDevice *GetBluetoothDevice(int iIndex);
BluetoothDevice *GetBluetoothDevice(LPTSTR bluetoothAddress);
//CSDPRecord *GetSDPRecord(BT_ADDR bluetoothAddress,SERVICE_
-------------------BTMap.cpp--
#include "stdafx.h"
#include "BluetoothDeviceMap.h"
BluetoothDeviceMap::
{
InitializeCriticalSection(&m_
}
BluetoothDeviceMap::~
{
DeleteCriticalSection(&m_
}
void BluetoothDeviceMap::
{
if((iIndex >=0)&&(iIndex < (int)size()))
{
BLUETOOTHDEVICEITERATOR iter = find(iIndex);
delete iter->second;
erase(iter);
}
}
void BluetoothDeviceMap::
{
EnterCriticalSection(&m_
removeBluetoothDevice(iIndex);
LeaveCriticalSection(&m_
}
void BluetoothDeviceMap::
{
EnterCriticalSection(&m_
for(BLUETOOTHDEVICEITERATOR iter = begin(); iter != end();iter++)
{
if(iter->second == pBluetoothDevice)
{
removeBluetoothDevice(iter->
break;
}
}
LeaveCriticalSection(&m_
}
void BluetoothDeviceMap::
{
EnterCriticalSection(&m_
for(BLUETOOTHDEVICEITERATOR iter = begin(); iter != end();iter++)
{
if(iter->second->GetBTAddress(
{
removeBluetoothDevice(iter->
break;
}
}
LeaveCriticalSection(&m_
}
void BluetoothDeviceMap::flush()
{
for (BLUETOOTHDEVICEITERATOR itr = begin();itr != end();itr++)
{
delete itr->second;
}
clear();
m_bIsDirty = false;
}
void BluetoothDeviceMap::Flush()
{
EnterCriticalSection(&m_
//flushToRegistry();
flush();
LeaveCriticalSection(&m_
}
int BluetoothDeviceMap::
{
int tmp = -1;
EnterCriticalSection(&m_
for(BLUETOOTHDEVICEITERATOR iter = begin(); iter!=end();iter++)
{
if(iter->second = pBluetoothDevice)
{
tmp = iter->first;
break;
}
}
LeaveCriticalSection(&m_
return tmp;
}
BluetoothDevice *BluetoothDeviceMap::
{
BluetoothDevice *tmpBTDevice = NULL;
EnterCriticalSection(&m_
int iIndex = -1;
CString aa;
//aa.Format(L"%s", pQueryResult->tcAddress);
if(findBluetoothDevice(
{
tmpBTDevice = new BluetoothDevice(pQueryResult->
insert(BLUETOOTHDEVICEMAPPAIR(
iIndex = size()-1;
}else
iIndex = -1;
return tmpBTDevice;
}
BluetoothDevice * BluetoothDeviceMap::
{
BLUETOOTHDEVICEITERATOR iter;
bool bFound = false;
for(iter=begin(); iter!=end();iter++)
{
if(iter->second->GetBTAddress(
{
iIndex = iter->first;
bFound = true;
break;
}
}
return bFound == true ? iter->second : NULL;
}
BluetoothDevice * BluetoothDeviceMap::
{
BluetoothDevice *p;
BLUETOOTHDEVICEITERATOR itr;
EnterCriticalSection(&m_
if (0 <= iIndex && iIndex < (int)size())
{
itr = find(iIndex);
p = itr->second;
}
LeaveCriticalSection(&m_
return itr->second;
}
BluetoothDevice * BluetoothDeviceMap::
{
EnterCriticalSection(&m_
int iIndex = -1;
BluetoothDevice *p = findBluetoothDevice(
LeaveCriticalSection(&m_
return p;
}
bool BluetoothDeviceMap::
{
bool bReturn = false;
if(dwIndex >= 0 && dwIndex < (DWORD)size() )
{
BLUETOOTHDEVICEITERATOR iter = find(dwIndex);
if(iter->second != NULL)
{
bReturn = iter->second->IsDevicePaired()
}
}
return bReturn;
}
------------------------------
#pragma once
class BluetoothDevice
{
private:
TCHAR m_DeviceName[100];
TCHAR m_tcAddress[100];
bool m_Paired;
public:
BluetoothDevice(void);
BluetoothDevice(TCHAR DeviceName[100], TCHAR tcAddress[100]);
virtual ~BluetoothDevice(void);
LPTSTR GetBTAddress(){return m_tcAddress;};
LPTSTR GetDeviceName(){return m_DeviceName;};
bool IsDevicePaired(){ return m_Paired;};
};
----------------------
#include "stdafx.h"
#include "BluetoothDevice.h"
BluetoothDevice::
{
}
BluetoothDevice::
{
_tcscpy(m_DeviceName,
_tcscpy(m_tcAddress,tcAddress)
}
BluetoothDevice::~
{
}
------------------------To Use---------------------------
Add:
BLUETOOTHDEVICE *tmpBTDevice = new BLUETOOTHDEVICE();
CString sssAddress = "myName";
_tcsncpy(tmpBTDevice->
CString sssAddress = "myAddress";
_tcsncpy(tmpBTDevice->
m_pCMSBluetooth->
_tcscpy(tmpBTDevice->
_tcscpy(tmpBTDevice->
Retrieve:
int CxxxBluetooth::
{
int iError = -100;
if(iIndex < GetDeviceCount())
{
BluetoothDevice *p = GetBluetoothDevice(iIndex); //GetBluetoothDevice: please see above function defination
//bsAddress = p->GetBTAddress(); //cannot do this, value is not copied!
_tcscpy(bsAddress,p->
iError = *bsAddress == 0? -1:0;
}
return iError;
}
int CxxxBluetooth::
{
int iError = -100;
if(iIndex < GetDeviceCount())
{
BluetoothDevice *p = GetBluetoothDevice(iIndex);
//bsName = p->GetDeviceName();
_tcscpy(bsName,p->
iError = *bsName == 0? -1:0;
}
return iError;
}
Storage: MAP in C++ and List in C# (1)
MAP in C++ and List in C#
=====================
(1) List in C#
For C#, if we want to store complicated data, we can use array list like following:
public class General
{
public BluetoothDevice[] DeviceList = new BluetoothDevice[(int)MaxSearchNumber.MaxDeviceNumer];
...
}
while BluetoothDevice is a Class:
public class BluetoothDevice
{
private string m_Name;
private string m_Address;
private bool m_Paired;
private int m_index;
private string m_type;
public string Type
{
get { return m_type; }
set { m_type = value; }
}
///
/// Constructor
///
public BluetoothDevice()
{
m_Name = "";
m_Address = "";
m_Paired = false;
m_index = -1;
m_type = "";
}
public int Index
{
get { return m_index; }
set { m_index = value; }
}
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
public string Address
{
get { return m_Address; }
set { m_Address = value; }
}
}
To use:
for (int i = 0; i < m_General.DeviceList.Length; i++)
m_General.DeviceList[i] = new BluetoothDevice();
m_General.DeviceList[m_General.DeviceCounter].Name = somevalue;
=====================
(1) List in C#
For C#, if we want to store complicated data, we can use array list like following:
public class General
{
public BluetoothDevice[] DeviceList = new BluetoothDevice[(int)
...
}
while BluetoothDevice is a Class:
public class BluetoothDevice
{
private string m_Name;
private string m_Address;
private bool m_Paired;
private int m_index;
private string m_type;
public string Type
{
get { return m_type; }
set { m_type = value; }
}
///
/// Constructor
///
public BluetoothDevice()
{
m_Name = "";
m_Address = "";
m_Paired = false;
m_index = -1;
m_type = "";
}
public int Index
{
get { return m_index; }
set { m_index = value; }
}
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
public string Address
{
get { return m_Address; }
set { m_Address = value; }
}
}
To use:
for (int i = 0; i < m_General.DeviceList.Length; i++)
m_General.DeviceList[i] = new BluetoothDevice();
m_General.DeviceList[m_
Monday, January 26, 2009
typedef struct and struct
There are _3_ ways of using struct. (not two as
mentioned in the previous e-mails). Here are all 3 different ways in a
program, with comments. Hope this clears up confusion.
typedef struct {
int data;
int text;
} S1;
// This will define a typedef for S1, in both C and in C++
struct S2 {
int data;
int text;
};
// This will define a typedef for S2 ONLY in C++, will create error in C.
struct {
int data;
int text;
} S3;
// This will declare S3 to be a variable of type struct.
// This is VERY different from the above two.
// This does not define a type. The above two defined type S1 and S2.
// This tells compiler to allocate memory for variable S3
void main()
{
S1 mine1; // this will work, S1 is a typedef.
S2 mine2; // this will work, S2 is also a typedef.
S3 mine3; // this will NOT work, S3 is not a typedef.
S1.data = 5; // Will give error because S1 is only a typedef.
S2.data = 5; // Will also give error because S1 is only a typedef.
S3.data = 5; // This will work, because S3 is a variable.
}
// That's how they different stuff are handy.
also !!!!!!!!!!! This next bit is important for people who using linked
lists etc.
struct S6 {
S6* ptr;
};
// This works, in C++ only.
typedef struct {
S7* ptr;
} S7;
// Although you would think this does the same thing in C OR C++....
// This DOES NOT work in C nor C++ !!!
Message send/receive between DLL and EXE
1. Message.h
#pragma once
#include "enums.h"
class CMessages
{
public:
static DWORD sm_dwNotificationMessage;
static HWND sm_hWndNotification;
static void PostMessage(NOTIFICATION_MESSAGES message,LPARAM info=0);
};
//enum.h
enum NOTIFICATION_MESSAGES
{
DISCOVERY_COMPLETE=0x100,
PAIRING_COMPLETE,
PAIRING_ERROR,
DISCOVERY_ERROR,
SERVICE_DISCOVERY_COMPLETE,
SERVICE_DISCOVERY_ERROR,
};
2. Message.cpp
#include "StdAfx.h"
#include "Messages.h"
DWORD CMessages::sm_dwNotificationMessage = RegisterWindowMessage(_T("Notification2A23463D-0006-4ec7-89CC-0A27AA71C4A8"));
HWND CMessages::sm_hWndNotification = NULL;
void CMessages::PostMessage(NOTIFICATION_MESSAGES message,LPARAM info)
{
::PostMessage(CMessages::sm_hWndNotification,CMessages::sm_dwNotificationMessage,message,info);
}
3. Usage:
CMessages::PostMessage(DISCOVERY_ERROR,iError);
Exported functions:
MYLIB_API unsigned WINAPI GetNotificationMessage();
MYLIB_API void WINAPI SetNotificationWindow(HWND hWndNotify) ;
CMessages m_CMessages;
HWND GetNotificationWnd() {return m_CMessages.sm_hWndNotification;}
DWORD GetNotificationMessage() {return m_CMessages.sm_dwNotificationMessage;}
void SetNotificationWindow(HWND hWndNotify) {m_CMessages.sm_hWndNotification = hWndNotify;}
4. In exe, using C#
#region MessageFunctions
//> ---------------------------------------------------------------------------
//> Class: NotificationWindow
//> Purpose: target window for bluetooth device events
//> ---------------------------------------------------------------------------
public class NotificationWindow : MessageWindow
{
// Create an instance of the form.
private Form1 m_FormConnWizard;
// Save a reference to the form so it can
// be notified when messages are received.
public NotificationWindow(Form1 formConnWizard)
{
this.m_FormConnWizard = formConnWizard;
}
// handle window messages from the bluetooth dll
protected override void WndProc(ref Message msg)
{
if (msg.Msg == m_FormConnWizard.GetMyNotificationMessage())
{
// call back to the form to handle this message
m_FormConnWizard.NotificationMessage(msg);
}
else{}
// Call the base WndProc method
// to process any messages not handled.
base.WndProc(ref msg);
}
}
private int GetMyNotificationMessage()
{
return (int)GetNotificationMessage();
}
private void NotificationMessage(Message msg)
{
switch ((uint)msg.WParam)
{
case (uint)NOTIFICATION_MESSAGES.DISCOVERY_COMPLETE:
{
KillSearchingTimer();
MessageBox.Show("DISCOVERY COMPLETE!");
break;
}
case (uint)NOTIFICATION_MESSAGES.DISCOVERY_ERROR:
{
//dx: revise the message
MessageBox.Show("...");
break;
}
case (uint)NOTIFICATION_MESSAGES.SERVICE_DISCOVERY_COMPLETE:
{
break;
}
case (uint)NOTIFICATION_MESSAGES.SERVICE_DISCOVERY_ERROR:
{
//MessageBox.Show(Properties.Resources.strDiscoveryError, "Service Discovery Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
break;
}
}
}
#endregion
public partial class Form1 : Form
{
NotificationWindow m_NotificationWindow;
public Form1()
{
m_NotificationWindow = new NotificationWindow(this);
SetNotificationWindow(m_NotificationWindow.Hwnd);
InitializeComponent();
}
..
}
[DllImport("xxx.dll", EntryPoint = "SetNotificationWindow", SetLastError = true)]
private extern static void SetNotificationWindow(IntPtr hWndNotify);
[DllImport("xxx.dll", EntryPoint = "GetNotificationMessage", SetLastError = true)]
private extern static uint GetNotificationMessage();
#pragma once
#include "enums.h"
class CMessages
{
public:
static DWORD sm_dwNotificationMessage;
static HWND sm_hWndNotification;
static void PostMessage(NOTIFICATION_
};
//enum.h
enum NOTIFICATION_MESSAGES
{
DISCOVERY_COMPLETE=0x100,
PAIRING_COMPLETE,
PAIRING_ERROR,
DISCOVERY_ERROR,
SERVICE_DISCOVERY_COMPLETE,
SERVICE_DISCOVERY_ERROR,
};
2. Message.cpp
#include "StdAfx.h"
#include "Messages.h"
DWORD CMessages::sm_
HWND CMessages::sm_
void CMessages::PostMessage(
{
::PostMessage(CMessages::sm_
}
3. Usage:
CMessages::PostMessage(
Exported functions:
MYLIB_API unsigned WINAPI GetNotificationMessage();
MYLIB_API void WINAPI SetNotificationWindow(HWND hWndNotify) ;
CMessages m_CMessages;
HWND GetNotificationWnd() {return m_CMessages.sm_
DWORD GetNotificationMessage() {return m_CMessages.sm_
void SetNotificationWindow(HWND hWndNotify) {m_CMessages.sm_
4. In exe, using C#
#region MessageFunctions
//> ------------------------------
//> Class: NotificationWindow
//> Purpose: target window for bluetooth device events
//> ------------------------------
public class NotificationWindow : MessageWindow
{
// Create an instance of the form.
private Form1 m_FormConnWizard;
// Save a reference to the form so it can
// be notified when messages are received.
public NotificationWindow(Form1 formConnWizard)
{
this.m_FormConnWizard = formConnWizard;
}
// handle window messages from the bluetooth dll
protected override void WndProc(ref Message msg)
{
if (msg.Msg == m_FormConnWizard.
{
// call back to the form to handle this message
m_FormConnWizard.
}
else{}
// Call the base WndProc method
// to process any messages not handled.
base.WndProc(ref msg);
}
}
private int GetMyNotificationMessage()
{
return (int)GetNotificationMessage();
}
private void NotificationMessage(Message msg)
{
switch ((uint)msg.WParam)
{
case (uint)NOTIFICATION_MESSAGES.
{
KillSearchingTimer();
MessageBox.Show("DISCOVERY COMPLETE!");
break;
}
case (uint)NOTIFICATION_MESSAGES.
{
//dx: revise the message
MessageBox.Show("...");
break;
}
case (uint)NOTIFICATION_MESSAGES.
{
break;
}
case (uint)NOTIFICATION_MESSAGES.
{
//MessageBox.Show(Properties.
break;
}
}
}
#endregion
public partial class Form1 : Form
{
NotificationWindow m_NotificationWindow;
public Form1()
{
m_NotificationWindow = new NotificationWindow(this);
SetNotificationWindow(m_
InitializeComponent();
}
..
}
[DllImport("xxx.dll", EntryPoint = "SetNotificationWindow", SetLastError = true)]
private extern static void SetNotificationWindow(IntPtr hWndNotify);
[DllImport("xxx.dll", EntryPoint = "GetNotificationMessage", SetLastError = true)]
private extern static uint GetNotificationMessage();
Thread Class for C++
1. CBaseThread.h
#pragma once
const DWORD TERMINATION_TIMEOUT = 10000;
class CBaseThread
{
protected:
DWORD m_dwThreadId;
HANDLE m_hTerminateEvent;
HANDLE m_hThread;
protected:
virtual DWORD ThreadProcedure(){return 0;};
public:
bool SetTerminationEvent(HANDLE hTerminationEvent);
bool ShouldTerminateThread();
virtual void TerminateThread();
static DWORD WINAPI ThreadProcedure(PVOID pVoid);
CBaseThread();
virtual ~CBaseThread();
};
2. CBaseThread.cpp
#include "stdafx.h"
#include "CBaseThread.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBaseThread::CBaseThread()
{
m_dwThreadId = NULL;
m_hTerminateEvent = NULL;
m_hThread = NULL;
m_hTerminateEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
ResetEvent(m_hTerminateEvent);
}
CBaseThread::~CBaseThread()
{
CloseHandle(m_hTerminateEvent);
}
//> ---------------------------------------------------------------------------
//> Function: CBaseThread::ThreadProcedure
//> Params: [in] void *pVoid data passed to the thread procedure
//> Returns: DWORD
//> Purpose: implements the static CBaseThread derived class thread procedure
//> by calling the derived class ThreadProcedure method
//> ---------------------------------------------------------------------------
DWORD CBaseThread::ThreadProcedure(void *pVoid)
{
CBaseThread *pThread = static_cast(pVoid);
return pThread->ThreadProcedure();
}
//> ---------------------------------------------------------------------------
//> Function: CBaseThread::TerminateThread
//> Params: none
//> Returns: void
//> Purpose: call this method to terminate the thread procedure
//> ---------------------------------------------------------------------------
void CBaseThread::TerminateThread()
{
// Signal the thread to terminate itself
SetEvent(m_hTerminateEvent);
// wait for the thread procedure to exit before returning
WaitForSingleObject(m_hThread,TERMINATION_TIMEOUT);
if (NULL != m_hThread)
{
CloseHandle(m_hThread);
}
}
//> ---------------------------------------------------------------------------
//> Function: CBaseThread::ShouldTerminateThread
//> Params: void
//> Returns: bool
//> Purpose: check to see if thread termination was requested
//> ---------------------------------------------------------------------------
bool CBaseThread::ShouldTerminateThread()
{
bool bReturn = false;
if (WAIT_OBJECT_0 == WaitForSingleObject(m_hTerminateEvent,0))
{
bReturn = true;
}
return bReturn;
}
3. Usage:
3.1. CDeviceDiscoveryThread.h
#pragma once
#include "cbasethread.h"
#include
#include
#include
#include
class CGigaBluetooth;
class CDeviceDiscoveryThread : public CBaseThread
{
private:
CGigaBluetooth *m_pCMSBluetooth;
protected:
virtual DWORD ThreadProcedure();
public:
static CDeviceDiscoveryThread *ThreadFactory(CGigaBluetooth *pCMSBluetooth);
CDeviceDiscoveryThread(CGigaBluetooth *pCMSBluetooth);
virtual ~CDeviceDiscoveryThread(void);
};
3.2. CDeviceDiscoveryThread.cpp
#include "StdAfx.h"
#include "GigaBluetooth.h"
#include "DeviceDiscoveryThread.h"
CDeviceDiscoveryThread::CDeviceDiscoveryThread(CGigaBluetooth *pCMSBluetooth)
{
ASSERT(NULL != pCMSBluetooth);
m_pCMSBluetooth = pCMSBluetooth;
}
CDeviceDiscoveryThread::~CDeviceDiscoveryThread(void)
{
}
//> ---------------------------------------------------------------------------
//> Function: ThreadFactory
//> Params: MSBluetooth *pMSBluetooth
//> Returns: CDeviceDiscoveryThread *
//> Purpose: creates CDeviceDiscoveryThread threads
//> ---------------------------------------------------------------------------
CDeviceDiscoveryThread * CDeviceDiscoveryThread::ThreadFactory(CGigaBluetooth *pCMSBluetooth)
{
CDeviceDiscoveryThread *pCDeviceDiscoveryThread = new CDeviceDiscoveryThread(pCMSBluetooth);
if (NULL != pCDeviceDiscoveryThread)
{
pCDeviceDiscoveryThread->m_hThread = ::CreateThread(NULL,0,CBaseThread::ThreadProcedure,pCDeviceDiscoveryThread,0,&pCDeviceDiscoveryThread->m_dwThreadId);
}
return pCDeviceDiscoveryThread;
}
//> ---------------------------------------------------------------------------
//> Function: ThreadProcedure
//> Params: none
//> Returns: DWORD
//> Purpose: implements the thread procedure
//> ---------------------------------------------------------------------------
DWORD CDeviceDiscoveryThread::ThreadProcedure()
{
Sleep(5000); //test
CMessages::PostMessage(DISCOVERY_COMPLETE);
return 0;
}
3.3.
CDeviceDiscoveryThread *m_pCDeviceDiscoveryThread;
m_pCDeviceDiscoveryThread = CDeviceDiscoveryThread::ThreadFactory(this);
return NULL != m_pCDeviceDiscoveryThread ? true : false;
#pragma once
const DWORD TERMINATION_TIMEOUT = 10000;
class CBaseThread
{
protected:
DWORD m_dwThreadId;
HANDLE m_hTerminateEvent;
HANDLE m_hThread;
protected:
virtual DWORD ThreadProcedure(){return 0;};
public:
bool SetTerminationEvent(HANDLE hTerminationEvent);
bool ShouldTerminateThread();
virtual void TerminateThread();
static DWORD WINAPI ThreadProcedure(PVOID pVoid);
CBaseThread();
virtual ~CBaseThread();
};
2. CBaseThread.cpp
#include "stdafx.h"
#include "CBaseThread.h"
//////////////////////////////
// Construction/Destruction
//////////////////////////////
CBaseThread::CBaseThread()
{
m_dwThreadId = NULL;
m_hTerminateEvent = NULL;
m_hThread = NULL;
m_hTerminateEvent = CreateEvent(NULL,TRUE,FALSE,
ResetEvent(m_hTerminateEvent);
}
CBaseThread::~CBaseThread()
{
CloseHandle(m_hTerminateEvent)
}
//> ------------------------------
//> Function: CBaseThread::ThreadProcedure
//> Params: [in] void *pVoid data passed to the thread procedure
//> Returns: DWORD
//> Purpose: implements the static CBaseThread derived class thread procedure
//> by calling the derived class ThreadProcedure method
//> ------------------------------
DWORD CBaseThread::ThreadProcedure(
{
CBaseThread *pThread = static_cast
return pThread->ThreadProcedure();
}
//> ------------------------------
//> Function: CBaseThread::TerminateThread
//> Params: none
//> Returns: void
//> Purpose: call this method to terminate the thread procedure
//> ------------------------------
void CBaseThread::TerminateThread()
{
// Signal the thread to terminate itself
SetEvent(m_hTerminateEvent);
// wait for the thread procedure to exit before returning
WaitForSingleObject(m_hThread,
if (NULL != m_hThread)
{
CloseHandle(m_hThread);
}
}
//> ------------------------------
//> Function: CBaseThread::
//> Params: void
//> Returns: bool
//> Purpose: check to see if thread termination was requested
//> ------------------------------
bool CBaseThread::
{
bool bReturn = false;
if (WAIT_OBJECT_0 == WaitForSingleObject(m_
{
bReturn = true;
}
return bReturn;
}
3. Usage:
3.1. CDeviceDiscoveryThread.h
#pragma once
#include "cbasethread.h"
#include
#include
#include
#include
class CGigaBluetooth;
class CDeviceDiscoveryThread : public CBaseThread
{
private:
CGigaBluetooth *m_pCMSBluetooth;
protected:
virtual DWORD ThreadProcedure();
public:
static CDeviceDiscoveryThread *ThreadFactory(CGigaBluetooth *pCMSBluetooth);
CDeviceDiscoveryThread(
virtual ~CDeviceDiscoveryThread(void);
};
3.2. CDeviceDiscoveryThread.cpp
#include "StdAfx.h"
#include "GigaBluetooth.h"
#include "DeviceDiscoveryThread.h"
CDeviceDiscoveryThread::
{
ASSERT(NULL != pCMSBluetooth);
m_pCMSBluetooth = pCMSBluetooth;
}
CDeviceDiscoveryThread::~
{
}
//> ------------------------------
//> Function: ThreadFactory
//> Params: MSBluetooth *pMSBluetooth
//> Returns: CDeviceDiscoveryThread *
//> Purpose: creates CDeviceDiscoveryThread threads
//> ------------------------------
CDeviceDiscoveryThread * CDeviceDiscoveryThread::
{
CDeviceDiscoveryThread *pCDeviceDiscoveryThread = new CDeviceDiscoveryThread(
if (NULL != pCDeviceDiscoveryThread)
{
pCDeviceDiscoveryThread->m_
}
return pCDeviceDiscoveryThread;
}
//> ------------------------------
//> Function: ThreadProcedure
//> Params: none
//> Returns: DWORD
//> Purpose: implements the thread procedure
//> ------------------------------
DWORD CDeviceDiscoveryThread::
{
Sleep(5000); //test
CMessages::PostMessage(
return 0;
}
3.3.
CDeviceDiscoveryThread *m_pCDeviceDiscoveryThread;
m_pCDeviceDiscoveryThread = CDeviceDiscoveryThread::
return NULL != m_pCDeviceDiscoveryThread ? true : false;
Friday, January 23, 2009
Create a MFC support (CString) win32 dll using EVC++
Step 1: EVC++
New project->WinCE Dynamic-link library->Simple Window CE DLL ->
Step 2: Add header aaa.h file:
#ifdef TWOTECHBT_EXPORTS //cannot use numbers here like "2TBT_EXPORTS" will get fatal error C1016: #if[n]def expected an identifier"
#define TWOTECHBTLIB_API __declspec(dllexport)
#else
#define TWOTECHBTLIB_API __declspec(dllimport)
#endif
// Use "C" naming convention for methods.
#ifdef __cplusplus
extern "C" {
#endif
TWOTECHBTLIB_API BOOL WINAPI Initialize();
TWOTECHBTLIB_API BOOL WINAPI Deinitialize();
TWOTECHBTLIB_API BOOL WINAPI GetLocalBluetoothAddressName(TCHAR *bsAddress, TCHAR *bsName);
#ifdef __cplusplus
}
#endif
Step 3: Settings->C/C++->Preprocessor->Add "TWOTECHBTLIB"
Step 4: aaa.cpp file: may need use following to replace default dllmain
BOOL APIENTRY Dllentry( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Step 5: in order to use CString, add following to stdafx.h
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include // MFC core and standard components
#include // MFC extensions
#if defined(_WIN32_WCE) && (_WIN32_WCE >= 211) && (_AFXDLL)
#include // MFC support for Internet Explorer 4 Common Controls
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
New project->WinCE Dynamic-link library->Simple Window CE DLL ->
Step 2: Add header aaa.h file:
#ifdef TWOTECHBT_EXPORTS //cannot use numbers here like "2TBT_EXPORTS" will get fatal error C1016: #if[n]def expected an identifier"
#define TWOTECHBTLIB_API __declspec(dllexport)
#else
#define TWOTECHBTLIB_API __declspec(dllimport)
#endif
// Use "C" naming convention for methods.
#ifdef __cplusplus
extern "C" {
#endif
TWOTECHBTLIB_API BOOL WINAPI Initialize();
TWOTECHBTLIB_API BOOL WINAPI Deinitialize();
TWOTECHBTLIB_API BOOL WINAPI GetLocalBluetoothAddressName(
#ifdef __cplusplus
}
#endif
Step 3: Settings->C/C++->Preprocessor-
Step 4: aaa.cpp file: may need use following to replace default dllmain
BOOL APIENTRY Dllentry( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Step 5: in order to use CString, add following to stdafx.h
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include
#include
#if defined(_WIN32_WCE) && (_WIN32_WCE >= 211) && (_AFXDLL)
#include
#endif
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include
#endif // _AFX_NO_AFXCMN_SUPPORT
Subscribe to:
Posts (Atom)