Friday, December 21, 2007

iQualityControl Notify Error

---------------------------
Hard coded break point
---------------------------
"IQualityControl::Notify not over-ridden from CBasePin. (IGNORE is OK)"
At line 2346 of C:\DXSDK\Samples\C++\DirectShow\BaseClasses\amfilter.cpp
Continue? (Cancel to debug)
---------------------------
Yes No Cancel
---------------------------
Solution :

This Error is displayed at runtime in a filter graph. So

for This Error I added the code as follows :
HRESULT Notify(IBaseFilter *pSelf,Quality q ) { return S_OK;}


in classes derived from CBasePin, Now it is working well...

Filter or DLL or .ocx registration Error

Filter or DLL or .ocx registration Error :
-------------------------------------------


Eventhough the DLL compiles and links well while registering the filter or DLL or.ocx using regsvr32 utility, I got this Error.

---------------------------
RegSvr32
---------------------------
.\Debug\HTTPWriterSinkFilterd.ax was loaded, but the DllRegisterServer entry point was not found.

.\Debug\HTTPWriterSinkFilterd.ax does not appear to be a .DLL or .OCX file.
---------------------------
OK
---------------------------

Solution Steps :
---------------


1.I Opened that DLL file in "Depends viewer" available in a visual studio tools
2. no function is exported from the DLL or filter file.
3.For Exporting the Functions, I used the .def file (module definition file).
4. Next I have opened the DLL,ax files in "Depends viewer" that are successfully registered
There the Dependency viewer displays the exported functions.
5. So the problem is in Exporting the functions
6. Next I opened the Project->Settings-> Linker->input ...

and I checked anywhere my .def file is specified there is nothing like that.

So I added the the following options

Project -> Settings-> Linker -> Input -> /DEF:My.def


Now I compiled the application and register it with regsvr32 utitily.
Now the registeration is done successfully .

if I opened that registered DLL in "Depends viewer", It displays the exported functions.

PostScript :
------------

In Some DLLs,even though they created the application as DLL,
without including this "/DEF:my.def", that dll also registers well.

Thursday, December 20, 2007

How to pass arguments from window to the windowProc function

How to pass arguments from window to the windowProc function :


CREATESTRUCT str;
int*i = new int();
*i = 40;
str->lpCreateParams = i;


WindowProc()
{
switch(Msg)
{

int* j = (int*) ((LPCREATESTRUCT(lParam)) ->lpCreateParams)

}
}


Another one way is we can also attach the Window parameter at the time of
WNDcLASS registration.

wc.cbWndExtra = i;

we can get this value using GetWindowLong()

int* j = (int*) GetWindowLong(hWnd,GWL_USERDATA);



SetWindowLong() fn is also available

we can also use GetWindowLongPtr() or SetWindowLongPtr() for this purpose.

Window Creation problem with WM_NCCREATE message

I registered the class in win32 SDK application.
I created the window using CreateWindow() fn.CreateWindow() fn returns NULL.
if I checked the GetLastError(), it returns 0( SUCCESS).window creation is failed but
GetLastError() also not returns valid Error information.
I handled the WM_NCCREATE message within a Window Procedure.


solution :

within the WindowProc() fn , I handled the WM_NCCREATE fn as follows :

case WM_NCCREATE :

break;



This is the reason for window creation failure. if we handled this WM_NCCREATE fn,
we must return TRUE. then only window creation will succeeds.

Friday, December 14, 2007

Identify the KeyFrame in a compressed input pin Filter

I developed the Netwriter Filter which accepts input as
Windows Media video.

within Netwriter Filter, how can we identify the KeyFrame ?

WMV is a compressed Format. How can we identify the Key Frame?

if the input pin of the transform filter is in compressed format,
How can we identify the KeyFrame ?...



Solution:
-----------

Using IMediaSample's IsSyncPoint() fn.

IsSyncPoint() fn returns S_OK if it is a KeyFrame.

otherwise it returns S_FALSE;


In Directshow, The technical name for the KeyFrame is Synchronization Point.
So we checked it as

IsSyncPoint ()

How to identify the protected wmv/asf file?

How to identify the protected wmv/asf file ?

IWMReader ->Open( File)

if the wmv or asf file is not able to open the file,
it will returns error code as license required.
After this one, we can use the IWMDRMReader to query the license details.

Sample program available in Windows media Format SDK samples :

DRMShow.exe - i "DRMShow.wmv" // DRMShow.wmv is available in directX media dir path

HTTPStreaming Problem without KeyFrame

1. I modified the IWMWriterAdvanced:: WriteStreamSample() fn's last parameter

as 0.( It Indicates the KeyFrame).

But I didnt get any display in Windows media player, but I got like

Buffer 98% complete...After certain interval it shows status as
Buffer 96% complete...

But It doesnt Display anything in media player.


2. How to change frame rate using the Transform Filter ? Is it Possible ?

yes it is possible.

Within FillBuffer() of the Source Filter we will Set the Frame rate ..
Just refer the PushSourceDesktop Filters. There we set the frame rate dynamically.

So it is also possible to change the frame rate thru transform filter.
We need to Set the Output Media Sample's StartTime and EndTime properly to achieve the specified frame rate.

How to change frame rate using the Transform Filter ? Is it Possible ?

How to change frame rate using the Transform Filter ? Is it Possible ?

yes it is possible.

Within FillBuffer() of the Source Filter we will Set the Frame rate ..
Just refer the PushSourceDesktop Filters. There we set the frame rate dynamically.

So it is also possible to change the frame rate thru transform filter.
We need to Set the Output Media Sample's StartTime and EndTime properly to achieve the specified frame rate.


This is what I Read :
----------------------

Hi, I think you must be more precise in describing what you want to achieve. Do you actually mean : display only about half of the frames, in half of the original clip duration, resulting in fact in a 100% speed up of the clip? Or something else?

As you are using EZRGB24, there are two things you can do easily :

1) you can skip a frame by returning S_FALSE in the transform function. Add in_framecount and out_framecount as members of the Filter.

HRESULT CEZrgb24::Transform(IMediaSample *pIn, IMediaSample *pOut){

in_frameount++; // we count all incoming samples

if (somefunction of in_framecount) { return S_FALSE}; // skip if somefunction is true

out_framecount++; // here we count only actually outgoing samples

// now we process the samples

HRESULT hr = copy(pIn, pOut);

......

}

2) you can adjust the sample times by setting the pOut samples start and stop times. In fact, if you skip samples, then you must retime all samples afterwards to make sure they are correctly timestamped for display by the renderer. You should do this in the same transform function after callling the copy function. Use the out_framecount to compute the start and stop times, and set them on the pOut sample using pOut->SetTime();

Typically, you should have :

tStart = out_counter * frameduration; tStop = tStart + frameduration;

You can speed up the display by reducing frameduration.

HTTPStream Rendering problem

HTTPStream Rendering problem :
---------------------------------
I have developed the transform filter for writing the WMV
data to the HTTP Stream.It is writing data properly .

But If I render the video thru windows media player by specifying URL,
It doesnt render data properly.


But Windows media player Shows the status like


Buffer 99% complete
Playing 302Kb/s

But it doesnt render anything on the screen.



Solution :
-------------
Previously I set the KeyFrame for every 60 frames...

I used the wmvnetwrite sample application for testing.
It is sending wmv data to the HTTp stream. For any wmv file, It has OnStreamSample() callback fn
For Every frame, it will calls this function.
within this function, I checked the last parameter( KeyFrame flag), if it is true,
then I will print the Key FrameFound and the frameNumber in debug string.

I noted one thing. Key Frame is in some random order.
So I set the keyframe for every 4 frames. Now it is working.
without WM_SF_CLEANPOINT(Indicates KeyFrame), windows media player will not render data properly.
How can we identify the Key Frames within a filter ?...

Wednesday, December 12, 2007

Remote Desktop Capture using DSNetwork Sender and Receiver

1.I modified the PushSource Desktop output pin's type as
MEDIATYPE_Stream, MEDIASUBTYPE_NULL or CLSID_NULL and So on.

2.In the Code SetSockopt() fn used for making the socket connection as multicast.
network interface card address is passed as an argument to this function ( SetsockOpt()).
I commented this code in DSNetwork Sender and Receiversample application in
DXSDK.
I modified the DSNetwork and DSReceiver Filter's property pages as Simply store
what we type as IPAddress.

3.I developed the raw transform filter which accepts MEDIATYPE_Stream as input and
gives MEDIATYPE_Video and we can connect it to the renderer

I tested this filter by doing the following :

PushSourceDesktop Filter ->Raw Transform filter-> LEAD RGB converter -> Video Render


within Raw Transform filter, I hardcoded the video width as 350 and height as 288, bitcount as 16

and RGB555.


4.next Integrated the raw transform filter with DSNetwork Sender and receiver.

5. within one PC, I captured the desktop using filter

Push Source Desktop_MEDIATypeStream -> MPEG Multicast Sender

6. On another PC, I constuct the graph as follows :


MPEG Multicast Receiver -> Raw Transform Filter -> Video Renderer


Actually the MPEG multicast receiver output pin's media type is MEDIAType_Stream...



Now the captured desktop is being displayed in remote system's video Renderer.


DrawBacks :
-----------
1. It consumes more network bandwidth...
we tested it within LAN. it requires more speed...

within this method, we got the framerate as 127.
Next we have to develop the Network Sender and Network Receiver as filter with WMV format...

Monday, December 10, 2007

UDP Server and Client application

UDPServer :
--------------
1.WSAStartup()
2.socket()
3.bind()
4.recv()
5.send()



UDPClient :
------------

1.WSAStartup()
2.gethostbyaddr()
3.socket()
4.connect()
5.send()
6.receive()



UDPServer:
----------
struct sockaddr_in local, from;
WSADATA wsaData;
SOCKET listen_socket, msgsock;


WSAStartup(0x202, &wsaData)
local.sin_family = AF_INET;
local.sin_addr.s_addr = (!ip_address) ? INADDR_ANY:inet_addr(ip_address);
local.sin_port = htons(port);

listen_socket = socket(AF_INET, SOCK_DGRAM,0);

if (listen_socket == INVALID_SOCKET){ //Error}

if (bind(listen_socket, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR){ //error}

msgsock = listen_socket;

retval = recvfrom(msgsock,Buffer, sizeof(Buffer), 0, (struct sockaddr *)&from, &fromlen);

if(retval == SOCKET_ERROR) {return;}

//send the received data back to the client...
retval = sendto(msgsock, Buffer, sizeof(Buffer), 0, (struct sockaddr *)&from, fromlen);



UDP client :
---------------

struct sockaddr_in server;

struct hostent *hp;

WSADATA wsaData;

SOCKET conn_socket;


if (isalpha(server_name[0]))

{ // server address is a name

hp = gethostbyname(server_name);

}

else

{ // Convert nnn.nnn address to a usable one

addr = inet_addr(server_name);

hp = gethostbyaddr((char *)&addr, 4, AF_INET);

}




memset(&server, 0, sizeof(server));

memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);

server.sin_family = hp->h_addrtype;

server.sin_port = htons(port);

conn_socket = socket(AF_INET, SOCK_DGRAM, 0);

if (connect(conn_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) { //Error}


retval = send(conn_socket, Buffer, sizeof(Buffer), 0);

retval = recv(conn_socket, Buffer, sizeof(Buffer), 0);

closesocket(conn_socket);

WSACleanup();

TCP Server and Client application

TCPServer :
-----------
struct sockaddr_in local, from;

WSADATA wsaData;

SOCKET listen_socket, msgsock;

if ((retval = WSAStartup(0x202, &wsaData)) != 0) {//Error}


local.sin_family = AF_INET;

local.sin_addr.s_addr = (!ip_address) ? INADDR_ANY:inet_addr(ip_address);

local.sin_port = htons(port);

listen_socket = socket(AF_INET, SOCK_STREAM,0);

if (bind(listen_socket, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR) { //Error Return}

//we can't use a UDP socket
if (listen(listen_socket,5) == SOCKET_ERROR) {//Error Return}

msgsock = accept(listen_socket, (struct sockaddr*)&from, &fromlen);

retval = recv(msgsock, Buffer, sizeof(Buffer), 0);

retval = send(msgsock, Buffer, sizeof(Buffer), 0);



TCP client :
-------------
struct sockaddr_in server;

struct hostent *hp;

WSADATA wsaData;

SOCKET conn_socket;

if ((retval = WSAStartup(0x202, &wsaData)) != 0) {//Error}

if (isalpha(server_name[0]))

{ // server address is a name

hp = gethostbyname(server_name);

}

else

{ // Convert nnn.nnn address to a usable one

addr = inet_addr(server_name);

hp = gethostbyaddr((char *)&addr, 4, AF_INET);

}

if(hp == NULL) { //Error return }

memset(&server, 0, sizeof(server));

memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);

server.sin_family = hp->h_addrtype;

server.sin_port = htons(port);

conn_socket = socket(AF_INET, SOCK_STREAM, 0); /* Open a socket */

if (connect(conn_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) {//Error Return}

retval = send(conn_socket, Buffer, sizeof(Buffer), 0);
retval = recv(conn_socket, Buffer, sizeof(Buffer), 0);


closesocket(conn_socket);

WSACleanup();

YUY2 to RGB24 conversion

#define FIXNUM 16
#define FIX(a, b) ((int)((a)*(1<<(b))))
#define UNFIX(a, b) ((a+(1<<(b-1)))>>(b))

// Approximate 255 by 256
#define ICCIRUV(x) (((x)<<8)/224)
#define ICCIRY(x) ((((x)-16)<<8)/219)

// Clip out-range values

#define CLIP(t) (((t)>255)?255:(((t)<0)?0:(t)))

#define GET_R_FROM_YUV(y, u, v) UNFIX((FIX(1.0, FIXNUM)*(y) + FIX(1.402, FIXNUM)*(v)), FIXNUM)

#define GET_G_FROM_YUV(y, u, v) UNFIX((FIX(1.0, FIXNUM)*(y) + FIX(-0.344, FIXNUM)*(u) + FIX(-0.714, FIXNUM)*(v)), FIXNUM)

#define GET_B_FROM_YUV(y, u, v) UNFIX((FIX(1.0, FIXNUM)*(y) + FIX(1.772, FIXNUM)*(u)), FIXNUM)

#define GET_Y_FROM_RGB(r, g, b) UNFIX((FIX(0.299, FIXNUM)*(r) + FIX(0.587, FIXNUM)*(g) + FIX(0.114, FIXNUM)*(b)), FIXNUM)

#define GET_U_FROM_RGB(r, g, b) UNFIX((FIX(-0.169, FIXNUM)*(r) + FIX(-0.331, FIXNUM)*(g) + FIX(0.500, FIXNUM)*(b)), FIXNUM)

#define GET_V_FROM_RGB(r, g, b) UNFIX((FIX(0.500, FIXNUM)*(r) + FIX(-0.419, FIXNUM)*(g) + FIX(-0.081, FIXNUM)*(b)), FIXNUM)



bool CYUVToRGB::YUV422P_to_RGB24V2(int width, int height, unsigned char *s,unsigned char *d)
{
int i;
unsigned char *p_dest;
unsigned char y1, u, y2, v;
int Y1, Y2, U, V;
unsigned char r, g, b;

p_dest = d;

int size = height * (width / 2);
unsigned long srcIndex = 0;
unsigned long dstIndex = 0;

try
{

for(i = 0 ; i < size ; i++)
{

y1 = s[srcIndex];
u = s[srcIndex+ 1];
y2 = s[srcIndex+ 2];
v = s[srcIndex+ 3];

Y1 = ICCIRY(y1);
U = ICCIRUV(u - 128);
Y2 = ICCIRY(y2);
V = ICCIRUV(v - 128);



r = CLIP(GET_R_FROM_YUV(Y1, U, V));
g = CLIP(GET_G_FROM_YUV(Y1, U, V));
b = CLIP(GET_B_FROM_YUV(Y1, U, V));


p_dest[dstIndex] = b;
p_dest[dstIndex + 1] = g;
p_dest[dstIndex + 2] = r;




dstIndex += 3;

r = CLIP(GET_R_FROM_YUV(Y2, U, V));
g = CLIP(GET_G_FROM_YUV(Y2, U, V));
b = CLIP(GET_B_FROM_YUV(Y2, U, V));

p_dest[dstIndex] = b;
p_dest[dstIndex + 1] = g;
p_dest[dstIndex + 2] = r;

dstIndex += 3;

srcIndex += 4;
}

return true;
}
catch(...)
{
OutputDebugString("\n YUV422P to RGB24V2 Failed");
return false;
}

}

Wednesday, December 05, 2007

How to use GDI+ ?

How to use GDI+ ?

For Gdi+, I added the Gdiplus.dll in C:\windows\system32 directory.
include the following lines in "stdafx.h"
#include
using namespace Gdiplus;


if the VC_EXTRALEAN or WIN32_LEAN_AND_MEAN is defined, the compiler generates
error message.

Remove these macros for using Gdi+ in VC++.
How to set output pin's media type as YUY2 ?...


we have to override the getmediaType() fn
HRESULT CRGBToYUV::GetMediaType(int iPosition, CMediaType *pMediaType)
{
// Is the input pin connected
if (m_pInput->IsConnected() == FALSE)
{
return E_UNEXPECTED;
}
// This should never happen
if (iPosition < 0)
{
return E_INVALIDARG;
}
// Do we have more items to offer
if (iPosition > 0) {
return VFW_S_NO_MORE_ITEMS;
}


CMediaType mt = m_pInput->CurrentMediaType();

VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*) mt.pbFormat;


VIDEOINFO *pvi = (VIDEOINFO*)pMediaType->AllocFormatBuffer(sizeof(VIDEOINFO));
if (pvi == 0)
return(E_OUTOFMEMORY);


ZeroMemory(pvi, pMediaType->cbFormat);
//pvi->AvgTimePerFrame = m_rtFrameLength;

pvi->bmiHeader.biWidth = vih->bmiHeader.biWidth;
pvi->bmiHeader.biHeight = vih->bmiHeader.biHeight;

m_iImageWidth = vih->bmiHeader.biWidth;
m_iImageHeight = vih->bmiHeader.biHeight;

pvi->bmiHeader.biCompression = MAKEFOURCC('Y', 'U', 'Y','2');//MAKEFOURCC('U', 'Y', 'V', 'Y');
pvi->bmiHeader.biBitCount = 16;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
// Clear source and target rectangles
SetRectEmpty(&(pvi->rcSource)); // we want the whole image area rendered
SetRectEmpty(&(pvi->rcTarget)); // no particular destination rectangle

pMediaType->SetType(&MEDIATYPE_Video);
pMediaType->SetFormatType(&FORMAT_VideoInfo);
pMediaType->SetTemporalCompression(FALSE);

// Work out the GUID for the subtype from the header info.
const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
pMediaType->SetSubtype(&SubTypeGUID);
pMediaType->SetSampleSize(pvi->bmiHeader.biSizeImage);

m_pRGBBuffer = new BYTE[pvi->bmiHeader.biWidth *pvi->bmiHeader.biHeight *3];
m_pYUVBuffer = new BYTE[pvi->bmiHeader.biWidth *pvi->bmiHeader.biHeight * 2];

return NOERROR;
}

Flipped Video problem in DirectShow

Normally in Directshow we face the Flipped image problem...

if we are having image buffer, how can we flip it using code ?

This is being done by the following code...

Solution :
------------

Here what we have done was...

ScanLine1- 0 - Scanwidth pixels
ScanLine2 - 0 to ScanWidth Pixels
upto
ScanLineN

we have to modify it as follows for Flipping the Image Data :

ScanLine N and its pixels...
ScanLine N-1 and its Pixels

upto
ScanLine 1



For Doing this, we have developed the following code :





void FlipUpDown(BYTE* pData,int gWidth,int gHeight,int gChannels)
{
BYTE* scan0 = pData;
BYTE* scan1 = pData + ((gWidth * gHeight * gChannels) - (gWidth * gChannels));

for (unsigned int y = 0; y < gHeight / 2; y++) {
for (unsigned int x = 0; x < gWidth * gChannels; x++)
{
BYTE temp = scan0[x];
scan0[x] = scan1[x];
scan1[x] = temp;
}
scan0 += gWidth * gChannels;
scan1 -= gWidth * gChannels;
}

Custom build for Registering a Filter at Compile time

For Registering the Filter using regsvr32 During compilation,
I have done the following :
1.Open the project-> properties ->Custom build tab
and set the

Description : "Registering Directshow Filter..."
commands : regsvr32 /c "$(TargetPath)"
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
Outputs : $(OutDir)\regsvr32.trg

Wednesday, November 28, 2007

Calculate the execution time of a function

Calculate the execution time of a function :
we can use timeGetTime() fn available in mmsystem.h .
For using this function,
we have to include the winmm.lib


DWORD dwStartTime = timeGetTime();
StretchBlt(); // which we want to find the execution time
DWORD dwEndTime = timeGetTime();

dwEndTime - dwStartTime is the execution time.

we can also use QueryPerformanceCounter() fn to find the execution time.

Monday, November 26, 2007

While using CString in a DLL, I got an error Because it is a win32 DLL.

While using CString in a DLL, I got an error Because it is a win32 DLL.

Solution :

I modified the project ->settings->General Tab-> Use MFC in a Shared DLL or Use MFC in a Static Library...

Afterwards I included the #include in "stdafx.h" header file, now the problem is solved...

How to Avoid name mangling of a function in a DLL:

How to Avoid name mangling of a function in a DLL:

I opened my DLL using Dependency viewer in visual studio tools.

The Dependency viewer showed the functions in it as follows :

For AAPI_CleanupRecorder() fn, it displays as follows :

?AAPI_CleanupRecorder@@YGHXZ

This is called name mangling.ToSupport function overloading this will happen.
How can we disable name mangling ?...


Solution :
------------

we can avoid name mangling using .def file in a DLL.

I added the AAPI_CleanupRecorder() fn in a .Def file as follows :


LIBRARY AAPIPC2TV.dll

EXPORTS

AAPI_CleanupRecorder @1

I compiled the DLL and then once again opened the DLL in a "Dependency viewer".

Now the AAPI_CleanupRecorder function is available in a Dependency viewer as follows :


AAPI_CleanupRecorder

But the Demerit of this approach is we can't use the function overlaoding.

Combo Box problem in MFC dialog application

Combo Box problem in MFC dialog application :
----------------------------------------------
1.I added the combo box to the dialog and added the string to the combo box using the following code...

CComboBox* combo = (CComboBox*) GetDlgItem( IDC_COMBO1 );
combo->AddString( "one" );
combo->AddString( "two" );
combo->AddString( "three" );

If I checked the count, it returns 3 But it didnt display the text "one,two,three" on screen.


Solution:
---------
Make sure you size the combo box in the resource editor so it is big enough. Click
on the little arrow and then drag the bottom handle square down. If you are doing it in
code, make sure the rect is big enough to fit the drop-down.

I opened the .rc file in a resource editor and modified the
combo box values , Now it displays the data .The problem is combo box height is not big to display
the combo box items in a drop down or drop List

Saturday, November 24, 2007

How to change the audio capture buffer size in DirectSound's CaptureSound application ?...

How to change the audio capture buffer size in DirectSound's CaptureSound application ?...


m_dwNotifySize = 3528;
Set this Value in CreateCaptureBuffer() fn,
before this line:

m_dwNotifySize = 3528;//AudioBufferSize
m_dwCaptureBufferSize = m_dwNotifySize * NUM_REC_NOTIFICATIONS;

 

Notification buffer size is used in this application to retrive data from the Circular buffer .


we can set any size to this notification buffer size and it will be used to retrive buffer size bytes from the circular buffer.

How to change the audio capture buffer size in DirectSound's CaptureSound application ?...

How to change the audio capture buffer size in DirectSound's CaptureSound application ?...


m_dwNotifySize = 3528;
Set this Value in CreateCaptureBuffer() fn,
before this line:

m_dwNotifySize = 3528;//AudioBufferSize
m_dwCaptureBufferSize = m_dwNotifySize * NUM_REC_NOTIFICATIONS;


Notification buffer size is passed to retrieve the data from the Circular buffer.
So we can set any buffer size , this will cause the change in buffer size.

Friday, November 23, 2007

Design time combo box problem in MFC Dialog application

I got the combo box problem in VC++ 6 dialog application as follows :

1.I added the Combo box with DropList property in a dialog application
2.I added the "control" member variable from the classwizard.
3.Within OnInitDialog() fn, I added the string to the combo box.
( m_cbo.AddString("Sundar");m_cbo.AddString('Sundar");)
But the added string is not displayed at runtime.

if I set the selected index for the combo box,

m_cbo.SetCurSel(0) , the selected index string "sundar" alone displayed in a combo box at
runtime.


4. To identify the problem, I created the Dynamic combo box by code ...

and Added the string , all the strings are displayed in a combo box.

But For Design time combo box, it didnt display the text.

unsupported operation was attempted error

In an MFC Dialog based application,
I didnt have a linker error but I got an error at runtime as follows;

"An unsupported operation was attempted."

Then the application is closed...


Reason for the Error :

I have added the Combo box in a MFC dialog application and added the control variable for it.

wizard will add the code as follows : DDX_Control(pDX, IDC_cboDeviceList, m_cboDevice);

later for some reason, I deleted the combo box from the dialog.

But the following code is still in my dialog application

DDX_Control(pDX, IDC_cboDeviceList, m_cboDevice);

and causes the error "the unsupported operation was attempted"

Vista supported multimedia technologies

Windows vista supports video and audio based development technology as follows:


1.Core Audio APIs
2.Directshow
3.Microsoft Media Foundation SDK
4.Windows portable devices
5.windows Audio and Video Codec and DSP APis
6.windows media device manager11 SDk
7.Windows movie maker 6.0 and windows DVD maker 1.0 SDK
8.Windows media Format 11 SDK
9.Windows media player 11 SDK
10.windows media Rights manager 10.1.2 SDK
11.Windows media Services 9 series

Sound card capturer in Vista

Today we tested the Directsound Audio capturer in vista ...
It is not working and we checked the waveIn Multimedia APis in vista..
That is also not working.

GraphBuilder way to convert RGB to YUY2

u need the RGB to YUY2 conversion as source Filter ?

we can do RGB to YUY2 in another way also .

Build the graph with Source Filter and add the color conversion filter to it.
and render it in screen.

Note : we have to set the input and output pin of the color conversion filter as
YUY2 .

RGB to YUY2 conversion

RGB to YUY2 :
1.Convert the RGB to YUY2 in my way and store it in a file
2.Using Color space converter convert it to YUY2 and dump it in memory

Compare these two things...

Other way is to

1.Initialize DirectDraw
2.Create the RGB Surface and copy the data to RGB surface
3.Create the YUY2 Surface and copy the RGB Surface to the YUY2 Surface
4.Lock the YUY2 Surface and get the buffer data...

RGB to YUV :

RGB to YUV conversion some formulas are available...
Bytes are arranged in this manner for YUY2
For the First 3 RGB Bytes we have to find the YU
YU
For the next 3 RGB bytes, we have to find the YV.
YV
This will be continued repeatedly.
YUYVYUYV

Capturing Data from Soundcard doesn't works

Previously I got an error in capturing data from Soundcard...

Solution :
1.Right click the speaker icon appeared in the right side of the Task bar
2.The "Master Volume" titled dialog box appear.
3.Select the menu properties-> Options
4.Look at the Mixer Device...

5.There Audio and video devices are appeared...
6.Select the Audio Input device.

7.Ensure the "Checked" state of RecordingControl, MiC Volume, LineVolume and Stereo Mix of an input Device

CWaveFile Usage

void MyFunc()
{
CWaveFile* g_pWaveFile = NULL;


g_pWaveFile = new CWaveFile;
HRESULT hr = S_OK;
hr = g_pWaveFile->Open(strFileName, &wfxCaptureWaveFormat, WAVEFILE_WRITE ) ;
if(FAILED(hr)
{
OutputDebugString("Error in writing WaveFileHeader");
return;
}

DWORD dwCaptureLength;
UINT dwDataWrote;
VOID* pbCaptureData = NULL;


// Write the data into the wav file
if( FAILED( hr = g_pWaveFile->Write( dwCaptureLength,
(BYTE*)pbCaptureData,
&dwDataWrote ) ) )

return DXTRACE_ERR_MSGBOX( TEXT("Write data to wavFile"), hr );


SAFE_DELETE(g_pWaveFile);

}

CWaveFile error in Directsound

I got this error while using CWaveFile class :


SoundTest.obj : error LNK2001: unresolved external symbol "public: __thiscall CWaveFile::CWaveFile(void)" (??0CWaveFile@@$$FQAE@XZ)
SoundTest.obj : error LNK2001: unresolved external symbol "public: __thiscall CWaveFile::~CWaveFile(void)" (??1CWaveFile@@$$FQAE@XZ)


Solution :
I added the dsutil.h and dsutil.cpp in my application.
I included the library files dxerr9.lib and winmm.lib



Next I got an error like this :

Creating library QuarticsAudioCaptureDLL___Win32_Debug_unicode/AAPIPC2TV.lib and object QuarticsAudioCaptureDLL___Win32_Debug_unicode/AAPIPC2TV.exp
dsutil.obj : error LNK2001: unresolved external symbol _IID_IDirectSound3DListener
dsutil.obj : error LNK2001: unresolved external symbol _IID_IDirectSoundNotify
dsutil.obj : error LNK2001: unresolved external symbol _IID_IDirectSound3DBuffer
QuarticsAudioCaptureDLL___Win32_Debug_unicode/AAPIPC2TV.dll : fatal error LNK1120: 3 unresolved externals
Error executing link.exe.

Solution :

include the library dxguid.lib in ur application

CWaveFile available in DirectSound

class CWaveFile
{
public:
WAVEFORMATEX* m_pwfx; // Pointer to WAVEFORMATEX structure
HMMIO m_hmmio; // MM I/O handle for the WAVE
MMCKINFO m_ck; // Multimedia RIFF chunk
MMCKINFO m_ckRiff; // Use in opening a WAVE file
DWORD m_dwSize; // The size of the wave file
MMIOINFO m_mmioinfoOut;
DWORD m_dwFlags;
BOOL m_bIsReadingFromMemory;
BYTE* m_pbData;
BYTE* m_pbDataCur;
ULONG m_ulDataSize;
CHAR* m_pResourceBuffer;

protected:
HRESULT ReadMMIO();
HRESULT WriteMMIO( WAVEFORMATEX *pwfxDest );

public:
CWaveFile();
~CWaveFile();

HRESULT Open( LPTSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags );
HRESULT OpenFromMemory( BYTE* pbData, ULONG ulDataSize, WAVEFORMATEX* pwfx, DWORD dwFlags );
HRESULT Close();

HRESULT Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead );
HRESULT Write( UINT nSizeToWrite, BYTE* pbData, UINT* pnSizeWrote );

DWORD GetSize();
HRESULT ResetFile();
WAVEFORMATEX* GetFormat() { return m_pwfx; };
};





//-----------------------------------------------------------------------------
// Name: CWaveFile::CWaveFile()
// Desc: Constructs the class. Call Open() to open a wave file for reading.
// Then call Read() as needed. Calling the destructor or Close()
// will close the file.
//-----------------------------------------------------------------------------
CWaveFile::CWaveFile()
{
m_pwfx = NULL;
m_hmmio = NULL;
m_pResourceBuffer = NULL;
m_dwSize = 0;
m_bIsReadingFromMemory = FALSE;
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::~CWaveFile()
// Desc: Destructs the class
//-----------------------------------------------------------------------------
CWaveFile::~CWaveFile()
{
Close();

if( !m_bIsReadingFromMemory )
SAFE_DELETE_ARRAY( m_pwfx );
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::Open()
// Desc: Opens a wave file for reading
//-----------------------------------------------------------------------------
HRESULT CWaveFile::Open( LPTSTR strFileName, WAVEFORMATEX* pwfx, DWORD dwFlags )
{
HRESULT hr;

m_dwFlags = dwFlags;
m_bIsReadingFromMemory = FALSE;

if( m_dwFlags == WAVEFILE_READ )
{
if( strFileName == NULL )
return E_INVALIDARG;
SAFE_DELETE_ARRAY( m_pwfx );

m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ );

if( NULL == m_hmmio )
{
HRSRC hResInfo;
HGLOBAL hResData;
DWORD dwSize;
VOID* pvRes;

// Loading it as a file failed, so try it as a resource
if( NULL == ( hResInfo = FindResource( NULL, strFileName, TEXT("WAVE") ) ) )
{
if( NULL == ( hResInfo = FindResource( NULL, strFileName, TEXT("WAV") ) ) )
return DXTRACE_ERR( TEXT("FindResource"), E_FAIL );
}

if( NULL == ( hResData = LoadResource( NULL, hResInfo ) ) )
return DXTRACE_ERR( TEXT("LoadResource"), E_FAIL );

if( 0 == ( dwSize = SizeofResource( NULL, hResInfo ) ) )
return DXTRACE_ERR( TEXT("SizeofResource"), E_FAIL );

if( NULL == ( pvRes = LockResource( hResData ) ) )
return DXTRACE_ERR( TEXT("LockResource"), E_FAIL );

m_pResourceBuffer = new CHAR[ dwSize ];
memcpy( m_pResourceBuffer, pvRes, dwSize );

MMIOINFO mmioInfo;
ZeroMemory( &mmioInfo, sizeof(mmioInfo) );
mmioInfo.fccIOProc = FOURCC_MEM;
mmioInfo.cchBuffer = dwSize;
mmioInfo.pchBuffer = (CHAR*) m_pResourceBuffer;

m_hmmio = mmioOpen( NULL, &mmioInfo, MMIO_ALLOCBUF | MMIO_READ );
}

if( FAILED( hr = ReadMMIO() ) )
{
// ReadMMIO will fail if its an not a wave file
mmioClose( m_hmmio, 0 );
return DXTRACE_ERR( TEXT("ReadMMIO"), hr );
}

if( FAILED( hr = ResetFile() ) )
return DXTRACE_ERR( TEXT("ResetFile"), hr );

// After the reset, the size of the wav file is m_ck.cksize so store it now
m_dwSize = m_ck.cksize;
}
else
{
m_hmmio = mmioOpen( strFileName, NULL, MMIO_ALLOCBUF |
MMIO_READWRITE |
MMIO_CREATE );
if( NULL == m_hmmio )
return DXTRACE_ERR( TEXT("mmioOpen"), E_FAIL );

if( FAILED( hr = WriteMMIO( pwfx ) ) )
{
mmioClose( m_hmmio, 0 );
return DXTRACE_ERR( TEXT("WriteMMIO"), hr );
}

if( FAILED( hr = ResetFile() ) )
return DXTRACE_ERR( TEXT("ResetFile"), hr );
}

return hr;
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::OpenFromMemory()
// Desc: copy data to CWaveFile member variable from memory
//-----------------------------------------------------------------------------
HRESULT CWaveFile::OpenFromMemory( BYTE* pbData, ULONG ulDataSize,
WAVEFORMATEX* pwfx, DWORD dwFlags )
{
m_pwfx = pwfx;
m_ulDataSize = ulDataSize;
m_pbData = pbData;
m_pbDataCur = m_pbData;
m_bIsReadingFromMemory = TRUE;

if( dwFlags != WAVEFILE_READ )
return E_NOTIMPL;

return S_OK;
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::ReadMMIO()
// Desc: Support function for reading from a multimedia I/O stream.
// m_hmmio must be valid before calling. This function uses it to
// update m_ckRiff, and m_pwfx.
//-----------------------------------------------------------------------------
HRESULT CWaveFile::ReadMMIO()
{
MMCKINFO ckIn; // chunk info. for general use.
PCMWAVEFORMAT pcmWaveFormat; // Temp PCM structure to load in.

m_pwfx = NULL;

if( ( 0 != mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) ) )
return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL );

// Check to make sure this is a valid wave file
if( (m_ckRiff.ckid != FOURCC_RIFF) ||
(m_ckRiff.fccType != mmioFOURCC('W', 'A', 'V', 'E') ) )
return DXTRACE_ERR( TEXT("mmioFOURCC"), E_FAIL );

// Search the input file for for the 'fmt ' chunk.
ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
if( 0 != mmioDescend( m_hmmio, &ckIn, &m_ckRiff, MMIO_FINDCHUNK ) )
return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL );

// Expect the 'fmt' chunk to be at least as large as ;
// if there are extra parameters at the end, we'll ignore them
if( ckIn.cksize < (LONG) sizeof(PCMWAVEFORMAT) )
return DXTRACE_ERR( TEXT("sizeof(PCMWAVEFORMAT)"), E_FAIL );

// Read the 'fmt ' chunk into .
if( mmioRead( m_hmmio, (HPSTR) &pcmWaveFormat,
sizeof(pcmWaveFormat)) != sizeof(pcmWaveFormat) )
return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL );

// Allocate the waveformatex, but if its not pcm format, read the next
// word, and thats how many extra bytes to allocate.
if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM )
{
m_pwfx = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) ];
if( NULL == m_pwfx )
return DXTRACE_ERR( TEXT("m_pwfx"), E_FAIL );

// Copy the bytes from the pcm structure to the waveformatex structure
memcpy( m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat) );
m_pwfx->cbSize = 0;
}
else
{
// Read in length of extra bytes.
WORD cbExtraBytes = 0L;
if( mmioRead( m_hmmio, (CHAR*)&cbExtraBytes, sizeof(WORD)) != sizeof(WORD) )
return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL );

m_pwfx = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) + cbExtraBytes ];
if( NULL == m_pwfx )
return DXTRACE_ERR( TEXT("new"), E_FAIL );

// Copy the bytes from the pcm structure to the waveformatex structure
memcpy( m_pwfx, &pcmWaveFormat, sizeof(pcmWaveFormat) );
m_pwfx->cbSize = cbExtraBytes;

// Now, read those extra bytes into the structure, if cbExtraAlloc != 0.
if( mmioRead( m_hmmio, (CHAR*)(((BYTE*)&(m_pwfx->cbSize))+sizeof(WORD)),
cbExtraBytes ) != cbExtraBytes )
{
SAFE_DELETE( m_pwfx );
return DXTRACE_ERR( TEXT("mmioRead"), E_FAIL );
}
}

// Ascend the input file out of the 'fmt ' chunk.
if( 0 != mmioAscend( m_hmmio, &ckIn, 0 ) )
{
SAFE_DELETE( m_pwfx );
return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL );
}

return S_OK;
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::GetSize()
// Desc: Retuns the size of the read access wave file
//-----------------------------------------------------------------------------
DWORD CWaveFile::GetSize()
{
return m_dwSize;
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::ResetFile()
// Desc: Resets the internal m_ck pointer so reading starts from the
// beginning of the file again
//-----------------------------------------------------------------------------
HRESULT CWaveFile::ResetFile()
{
if( m_bIsReadingFromMemory )
{
m_pbDataCur = m_pbData;
}
else
{
if( m_hmmio == NULL )
return CO_E_NOTINITIALIZED;

if( m_dwFlags == WAVEFILE_READ )
{
// Seek to the data
if( -1 == mmioSeek( m_hmmio, m_ckRiff.dwDataOffset + sizeof(FOURCC),
SEEK_SET ) )
return DXTRACE_ERR( TEXT("mmioSeek"), E_FAIL );

// Search the input file for the 'data' chunk.
m_ck.ckid = mmioFOURCC('d', 'a', 't', 'a');
if( 0 != mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL );
}
else
{
// Create the 'data' chunk that holds the waveform samples.
m_ck.ckid = mmioFOURCC('d', 'a', 't', 'a');
m_ck.cksize = 0;

if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) )
return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL );

if( 0 != mmioGetInfo( m_hmmio, &m_mmioinfoOut, 0 ) )
return DXTRACE_ERR( TEXT("mmioGetInfo"), E_FAIL );
}
}

return S_OK;
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::Read()
// Desc: Reads section of data from a wave file into pBuffer and returns
// how much read in pdwSizeRead, reading not more than dwSizeToRead.
// This uses m_ck to determine where to start reading from. So
// subsequent calls will be continue where the last left off unless
// Reset() is called.
//-----------------------------------------------------------------------------
HRESULT CWaveFile::Read( BYTE* pBuffer, DWORD dwSizeToRead, DWORD* pdwSizeRead )
{
if( m_bIsReadingFromMemory )
{
if( m_pbDataCur == NULL )
return CO_E_NOTINITIALIZED;
if( pdwSizeRead != NULL )
*pdwSizeRead = 0;

if( (BYTE*)(m_pbDataCur + dwSizeToRead) >
(BYTE*)(m_pbData + m_ulDataSize) )
{
dwSizeToRead = m_ulDataSize - (DWORD)(m_pbDataCur - m_pbData);
}

CopyMemory( pBuffer, m_pbDataCur, dwSizeToRead );

if( pdwSizeRead != NULL )
*pdwSizeRead = dwSizeToRead;

return S_OK;
}
else
{
MMIOINFO mmioinfoIn; // current status of m_hmmio

if( m_hmmio == NULL )
return CO_E_NOTINITIALIZED;
if( pBuffer == NULL || pdwSizeRead == NULL )
return E_INVALIDARG;

if( pdwSizeRead != NULL )
*pdwSizeRead = 0;

if( 0 != mmioGetInfo( m_hmmio, &mmioinfoIn, 0 ) )
return DXTRACE_ERR( TEXT("mmioGetInfo"), E_FAIL );

UINT cbDataIn = dwSizeToRead;
if( cbDataIn > m_ck.cksize )
cbDataIn = m_ck.cksize;

m_ck.cksize -= cbDataIn;

for( DWORD cT = 0; cT < cbDataIn; cT++ )
{
// Copy the bytes from the io to the buffer.
if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
{
if( 0 != mmioAdvance( m_hmmio, &mmioinfoIn, MMIO_READ ) )
return DXTRACE_ERR( TEXT("mmioAdvance"), E_FAIL );

if( mmioinfoIn.pchNext == mmioinfoIn.pchEndRead )
return DXTRACE_ERR( TEXT("mmioinfoIn.pchNext"), E_FAIL );
}

// Actual copy.
*((BYTE*)pBuffer+cT) = *((BYTE*)mmioinfoIn.pchNext);
mmioinfoIn.pchNext++;
}

if( 0 != mmioSetInfo( m_hmmio, &mmioinfoIn, 0 ) )
return DXTRACE_ERR( TEXT("mmioSetInfo"), E_FAIL );

if( pdwSizeRead != NULL )
*pdwSizeRead = cbDataIn;

return S_OK;
}
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::Close()
// Desc: Closes the wave file
//-----------------------------------------------------------------------------
HRESULT CWaveFile::Close()
{
if( m_dwFlags == WAVEFILE_READ )
{
mmioClose( m_hmmio, 0 );
m_hmmio = NULL;
SAFE_DELETE_ARRAY( m_pResourceBuffer );
}
else
{
m_mmioinfoOut.dwFlags |= MMIO_DIRTY;

if( m_hmmio == NULL )
return CO_E_NOTINITIALIZED;

if( 0 != mmioSetInfo( m_hmmio, &m_mmioinfoOut, 0 ) )
return DXTRACE_ERR( TEXT("mmioSetInfo"), E_FAIL );

// Ascend the output file out of the 'data' chunk -- this will cause
// the chunk size of the 'data' chunk to be written.
if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) )
return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL );

// Do this here instead...
if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) )
return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL );

mmioSeek( m_hmmio, 0, SEEK_SET );

if( 0 != (INT)mmioDescend( m_hmmio, &m_ckRiff, NULL, 0 ) )
return DXTRACE_ERR( TEXT("mmioDescend"), E_FAIL );

m_ck.ckid = mmioFOURCC('f', 'a', 'c', 't');

if( 0 == mmioDescend( m_hmmio, &m_ck, &m_ckRiff, MMIO_FINDCHUNK ) )
{
DWORD dwSamples = 0;
mmioWrite( m_hmmio, (HPSTR)&dwSamples, sizeof(DWORD) );
mmioAscend( m_hmmio, &m_ck, 0 );
}

// Ascend the output file out of the 'RIFF' chunk -- this will cause
// the chunk size of the 'RIFF' chunk to be written.
if( 0 != mmioAscend( m_hmmio, &m_ckRiff, 0 ) )
return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL );

mmioClose( m_hmmio, 0 );
m_hmmio = NULL;
}

return S_OK;
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::WriteMMIO()
// Desc: Support function for reading from a multimedia I/O stream
// pwfxDest is the WAVEFORMATEX for this new wave file.
// m_hmmio must be valid before calling. This function uses it to
// update m_ckRiff, and m_ck.
//-----------------------------------------------------------------------------
HRESULT CWaveFile::WriteMMIO( WAVEFORMATEX *pwfxDest )
{
DWORD dwFactChunk; // Contains the actual fact chunk. Garbage until WaveCloseWriteFile.
MMCKINFO ckOut1;

dwFactChunk = (DWORD)-1;

// Create the output file RIFF chunk of form type 'WAVE'.
m_ckRiff.fccType = mmioFOURCC('W', 'A', 'V', 'E');
m_ckRiff.cksize = 0;

if( 0 != mmioCreateChunk( m_hmmio, &m_ckRiff, MMIO_CREATERIFF ) )
return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL );

// We are now descended into the 'RIFF' chunk we just created.
// Now create the 'fmt ' chunk. Since we know the size of this chunk,
// specify it in the MMCKINFO structure so MMIO doesn't have to seek
// back and set the chunk size after ascending from the chunk.
m_ck.ckid = mmioFOURCC('f', 'm', 't', ' ');
m_ck.cksize = sizeof(PCMWAVEFORMAT);

if( 0 != mmioCreateChunk( m_hmmio, &m_ck, 0 ) )
return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL );

// Write the PCMWAVEFORMAT structure to the 'fmt ' chunk if its that type.
if( pwfxDest->wFormatTag == WAVE_FORMAT_PCM )
{
if( mmioWrite( m_hmmio, (HPSTR) pwfxDest,
sizeof(PCMWAVEFORMAT)) != sizeof(PCMWAVEFORMAT))
return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL );
}
else
{
// Write the variable length size.
if( (UINT)mmioWrite( m_hmmio, (HPSTR) pwfxDest,
sizeof(*pwfxDest) + pwfxDest->cbSize ) !=
( sizeof(*pwfxDest) + pwfxDest->cbSize ) )
return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL );
}

// Ascend out of the 'fmt ' chunk, back into the 'RIFF' chunk.
if( 0 != mmioAscend( m_hmmio, &m_ck, 0 ) )
return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL );

// Now create the fact chunk, not required for PCM but nice to have. This is filled
// in when the close routine is called.
ckOut1.ckid = mmioFOURCC('f', 'a', 'c', 't');
ckOut1.cksize = 0;

if( 0 != mmioCreateChunk( m_hmmio, &ckOut1, 0 ) )
return DXTRACE_ERR( TEXT("mmioCreateChunk"), E_FAIL );

if( mmioWrite( m_hmmio, (HPSTR)&dwFactChunk, sizeof(dwFactChunk)) !=
sizeof(dwFactChunk) )
return DXTRACE_ERR( TEXT("mmioWrite"), E_FAIL );

// Now ascend out of the fact chunk...
if( 0 != mmioAscend( m_hmmio, &ckOut1, 0 ) )
return DXTRACE_ERR( TEXT("mmioAscend"), E_FAIL );

return S_OK;
}




//-----------------------------------------------------------------------------
// Name: CWaveFile::Write()
// Desc: Writes data to the open wave file
//-----------------------------------------------------------------------------
HRESULT CWaveFile::Write( UINT nSizeToWrite, BYTE* pbSrcData, UINT* pnSizeWrote )
{
UINT cT;

if( m_bIsReadingFromMemory )
return E_NOTIMPL;
if( m_hmmio == NULL )
return CO_E_NOTINITIALIZED;
if( pnSizeWrote == NULL || pbSrcData == NULL )
return E_INVALIDARG;

*pnSizeWrote = 0;

for( cT = 0; cT < nSizeToWrite; cT++ )
{
if( m_mmioinfoOut.pchNext == m_mmioinfoOut.pchEndWrite )
{
m_mmioinfoOut.dwFlags |= MMIO_DIRTY;
if( 0 != mmioAdvance( m_hmmio, &m_mmioinfoOut, MMIO_WRITE ) )
return DXTRACE_ERR( TEXT("mmioAdvance"), E_FAIL );
}

*((BYTE*)m_mmioinfoOut.pchNext) = *((BYTE*)pbSrcData+cT);
(BYTE*)m_mmioinfoOut.pchNext++;

(*pnSizeWrote)++;
}

return S_OK;
}

How to call the DLL from DLL client

For DLL client application :
--------------------------------

1.we have to copy the header file from the DLL application
2.include the library path where the library file resides and copy the library and DLL fucntions
to the application path.
3.we have to include the DLL application's header file in DLL client application and
Call the Function in DLL client application before that

Deleting STL list pointers

list TestList;
list:: iterator Iter;

// Adding data to the
Iter = TestList.begin();
TestList.insert(new Test(),Iter);
Iter++;
TestList.insert(new Test(),Iter);


Test* pT = NULL;




//Removing All the pointers from the STL list as follows :


while( TestList.size() > 0)
{
Iter = TestList.begin();
pT = *Iter;
TestList.remove(pT); //Remove the item from the list
SAFE_DELETE(pT); //Free the resource
}

Thursday, November 01, 2007

C# File Access Problem

 
 I faced the problem in C# file access that is as follows :
 
 
C# file accessing Sample :
-------------------------------------


// Specify file, instructions, and privelegdes
FileStream file = new FileStream("test.txt", FileMode.Open);

// Create a new stream to read from a file
StreamReader sr = new StreamReader(file);

// Read contents of file into a string
string s = sr.ReadToEnd();

// Close StreamReader
sr.Close();

// Close file
file.Close();

  Everywhere people used the sample like this...

I also followed this sample during the development.
 I read the char by char from the streamReader object.

test.txt file is less than 1024 bytes size then the problem will not arise.

But if  file size is greater than 1024 bytes, I got the problem.


 I read the char by char from the StreamReader object.

 char[] szChar;
 szChar = new char[1];
                   strmReader.Read(szChar,0,1);

  
 After reaching the 1024 th character, I got the first character from the file...

So the StreamReader doesnt Read characters from file after 1024 characters.


Reason :

 By default StreamReader buffer size is 1024 bytes. we can also allocate the StreamReader buffer size.

if we read characters after 1024th character, StreamReader's Read() fn will returns the first character from the stream.

This will be repeated...


To avoid this problem, I allocated the StreamReader's size as File Size.
Now  we can traverse from beginning of the file to the end of the file.The code is as follows :

 

 FileStream myFile = new FileStream("test.txt",FileMode.Open);
 FileInfo fileInfo  = new FileInfo("test.txt");
 int FileLength = (int)fileInfo.Length; 
 StreamReader strmReader = new StreamReader( myFile, System.Text.Encoding.UTF8,false, FileLength);

 

 

 

 

 

 

 


 

Saturday, October 20, 2007

Dshow Companies

1.LG

2.Flextronics

3.Wipro

4.NVIDIA

5.Tata Elxsi

6.Honeywell

7.SAMSUNG

8.ARICENT

9.ST MICR0LECTRONIC

10.CADENC

11.QUALCOMM

12.L&T

13.ALCATEL
14.Sony
1.LG
 
2.Flextronics
 
3.Wipro
 
4.NVIDIA
 
5.Tata Elxsi
 
6.Honeywell
 
7.SAMSUNG
 
8.ARICENT
 
9.ST MICR0LECTRONIC
 
10.CADENC
 
11.QUALCOMM
 
12.L&T
 
13.ALCATEL
14.Sony
 
 

Thursday, September 27, 2007

ListView header problem in C#

private void CreateMyListView()
{
// Create a new ListView control.
ListView listView1 = new ListView();
listView1.Bounds = new Rectangle(new Point(10, 10), new Size(300, 200));

// Set the view to show details.
listView1.View = View.Details;
// Allow the user to edit item text.
listView1.LabelEdit = true;
// Allow the user to rearrange columns.
listView1.AllowColumnReorder = true;
// Display check boxes.
listView1.CheckBoxes = true;
// Select the item and subitems when selection is made.
listView1.FullRowSelect = true;
// Display grid lines.
listView1.GridLines = true;
// Sort the items in the list in ascending order.
listView1.Sorting = SortOrder.Ascending;

// Create three items and three sets of subitems for each item.
ListViewItem item1 = new ListViewItem("item1", 0);
// Place a check mark next to the item.
item1.Checked = true;
item1.SubItems.Add("1");
item1.SubItems.Add("2");
item1.SubItems.Add("3");
ListViewItem item2 = new ListViewItem("item2", 1);
item2.SubItems.Add("4");
item2.SubItems.Add("5");
item2.SubItems.Add("6");
ListViewItem item3 = new ListViewItem("item3", 0);
// Place a check mark next to the item.
item3.Checked = true;
item3.SubItems.Add("7");
item3.SubItems.Add("8");
item3.SubItems.Add("9");

// Create columns for the items and subitems.
listView1.Columns.Add("Item Column", -2, HorizontalAlignment.Left);
listView1.Columns.Add("Column 2", -2, HorizontalAlignment.Left);
listView1.Columns.Add("Column 3", -2, HorizontalAlignment.Left);
listView1.Columns.Add("Column 4", -2, HorizontalAlignment.Center);

//Add the items to the ListView.
listView1.Items.AddRange(new ListViewItem[] { item1, item2, item3 });
/*
// Create two ImageList objects.
ImageList imageListSmall = new ImageList();
ImageList imageListLarge = new ImageList();

// Initialize the ImageList objects with bitmaps.
imageListSmall.Images.Add(Bitmap.FromFile("C:\\MySmallImage1.bmp"));
imageListSmall.Images.Add(Bitmap.FromFile("C:\\MySmallImage2.bmp"));
imageListLarge.Images.Add(Bitmap.FromFile("C:\\MyLargeImage1.bmp"));
imageListLarge.Images.Add(Bitmap.FromFile("C:\\MyLargeImage2.bmp"));

//Assign the ImageList objects to the ListView.
listView1.LargeImageList = imageListLarge;
listView1.SmallImageList = imageListSmall;
*/
// Add the ListView to the control collection.
this.Controls.Add(listView1);
}

Wednesday, September 26, 2007

DllMain in a DLL

DllMain Called with Flags

There are several conditions where DllMain is called with the DLL_PROCESS_ATTACH, DLL_PROCESS_DETACH, DLL_THREAD_ATTACH, or DLL_THREAD_DETACH flags.

The DLL_PROCESS_ATTACH flag is sent when a DLL is loaded into the address space of a process. This occurs in both situations where the DLL is loaded with LoadLibrary, or implicitly during application load. When the DLL is implicitly loaded, DllMain is executed with DLL_PROCESS_ATTACH before the processes enter WinMain. When the DLL is explicitly loaded, DllMain is executed with DLL_PROCESS_ATTACH before LoadLibrary returns.

The DLL_PROCESS_DETACH flag is sent when a process cleanly unloads the DLL from its address space. This occurs during a call to FreeLibrary, or if the DLL is implicitly loaded, a clean process exit. When a DLL is detaching from a process, the individual threads of the process do not call the DLL_THREAD_DETACH flag.

The DLL_THREAD_ATTACH flag is sent when a new thread is being created in a process already attached to the DLL. Threads in existence before the process attached to a DLL will not send the DLL_THREAD_ATTACH flag. The first thread to attach to the DLL does not send the DLL_THREAD_ATTACH flag; it sends the DLL_PROCESS_ATTACH flag instead.

The DLL_THREAD_DETACH flag is sent when a thread is exiting cleanly. There is a situation when DllMain may be called when the thread did not first send the DLL_THREAD_ATTACH flag. This can happen if there are other threads still running and the original thread exits cleanly. The thread originally called DllMain with the DLL_PROCESS_ATTACH flag and later calls DllMain with the DLL_THREAD_DETACH flag. You may also have DllMain being called with DLL_THREAD_DETACH if a thread exits but was running in the process before the call to LoadLibrary.

 

Situations Where DllMain is Not Called or Is Bypassed

DllMain may not be called at all in dire situations where a thread or process was killed by a call to TerminateThread or TerminateProcess. These functions bypass calling DllMain. They are recommended only as a last resort. Data owned by the thread or process is at risk of loss because the process or thread could not shut itself down properly.

DllMain may be bypassed intentionally by a process if it calls DisableThreadLibraryCalls. This function (available with Windows 95 and Windows NT versions 3.5 and later) disables all DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications for a DLL. This enables a process to reduce its code size and working set. For more information on this function, see the SDK documentation on DisableThreadLibraryCalls.

C# Tips

I am working in C# 2005

1.Modal Dialog and Modeless Dialog in C#
2.C# MDI forms
3.Opening the Chm file
4.CheckOnClick property in a menuitem
 set the Checked property as true or false

Modal Dialog and Modeless Dialog in C# :
-------------------------------------------------------------
if we are having Two Forms in our Project,  From the  Form1, we will display the Form2 as Modal and Modeless dialog.

Class Form2
{

}

class  Form1
{
     void btnShowForm2_Click()
     {
 Form2 frm = new Form2();

 frm.Show() ;// For Modeless Dialog
 frm.ShowDialog() ;//  This is for Modal dialog
 
     }
}

2.C# MDI forms
----------------------
     From Main Form, we will create the another Form means
this can be made as MDI forms.

 Wecan display more than one forms at a time in MDI forms.

For the parent Form, we have to enable the IsMdiContainer property as true.

and then drill down in to the coding as follows :

 class ChildForm
 {
 }
 class ParentForm
 {
  
  //this.IsMdiContainer = true;

  private void mnuShowChildForm_Click()
  {
   ChildForm frm = new ChildForm();
   frm.MdiParent = this;
   frm.Show();
  }
 }


Only MdiParent property of the child form is set to the Parent form's Object.

 
3. Sometimes we faced the problem in opening chm files content display problem.

while opening the chm file, sometimes it displays the dialog with "always ask before opening this file"  check box.

if this check box is not selected by us then it will not display the chm contents. So To display the chm file contents, we must enable

"always ask before opening this file"  check box.

4.CheckOnClick property in a menu item  Sometimes we may need Checked property in a menuitem. For Instance, if the user selects the menuitem then it will show the Checked mark in a menuitem and if we select once again, the checkbox will
not be shown. this selection process takes place continously like Toggle on or off.

 
 For Doing this one, the menu item is having the property CheckOnClick .

if we enable this property, then we can display the check mark and we can change the execution behavior also based on the check mark.

 CheckedState property is set to true or false based on whether the check  mark is currently displayed in a menuitem or not.

This feature can be aptly used in the following Scenario.

 if we have MDI parent form, based on the checked selection of the menuitem we have to display the MDI child form.


if the menuitem is selected for the first time, we have to display the child form. if the menuitem is selected once again, then the child form must be

hided...

 By default set the menuitem's CheckOnClick property as true and Checked property as false.

  For doing this one , add the menu event handler as follows :

 void mnuShowChildForm_Click()
 {
  if( mnuShowChildForm.Checked == true)
  {
   childFormObject.Show();
  }
  else
  {
   childFormObject.Hide();
  }
 }
 

 

 

Tuesday, September 18, 2007

MFC message maps

MFC Message Maps:
MFC provides an alternative to the switch statement used in traditional Windows programs to handle messages sent to a window. A mapping from messages to member-functions may be defined so that when a message is to be handled by a window, the appropriate member function is called automatically.

This message-map facility is designed to be similar to virtual functions but has additional benefits not possible with C++ virtual functions.


Defining a Message Map:

1.The DECLARE_MESSAGE_MAP macro declares three members for a class.

A private array of AFX_MSGMAP_ENTRY entries called _messageEntries,


A protected AFX_MSGMAP structure called messageMap that points to the _messageEntries array


A protected virtual function called GetMessageMap that returns the address of messageMap.
This macro should be placed in the declaration of any class using message maps. By convention, it is at the end of the class declaration. For example:

class CMyWnd : public CMyParentWndClass
{
// my stuff...

protected:
//{{AFX_MSG(CMyWnd)
afx_msg void OnPaint();
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
};


The message map's table is defined with a set of macros that expand to message map
entries. A table begins with a BEGIN_MESSAGE_MAP macro call, which defines the class that is handled by this message map and the parent class to which unhandled messages are passed. The
table ends with the END_MESSAGE_MAP macro call.

Between these two macro calls is an entry for each message to be handled by this message map. Every standard Windows message has a macro of the form ON_WM_xxx (where xxx is the name of the message) that generates an entry for that message.

CObject services

CObject Services :
Cobject provides basic services needed for all the classes.

1.Supports serialization
2.run-time class information
3.Dynamic Object Creation
4.Object diagnostic output (Debugging)
5.Compatibility with collection classes

The first-level macros, DECLARE_DYNAMIC and IMPLEMENT_DYNAMIC, permit run-time access to the class name
and its position in the hierarchy. This, in turn, allows meaningful diagnostic dumping and dynamic Object creation.

The second-level macros, DECLARE_SERIAL and IMPLEMENT_SERIAL, include all the functionality of the first-level macros,
and they enable an object to be “serialized” to and from an “archive.”

MFC collection classes are derived from CObject So we can store any class( derived from CObject) into the collection class.



Serialization Example :
----------------------------------

class CMyObject : public CObject
{
// ...Member functions
public:
CMyObject() { }
virtual void Serialize( CArchive& ar ) { }

// Implementation
protected:
DECLARE_SERIAL( CMyObject )
};


class COtherObject : public CObject
{
// ...Member functions
public:
COtherObject() { }
virtual void Serialize( CArchive& ar ) { }

// Implementation
protected:
DECLARE_SERIAL( COtherObject )
};


class CCompoundObject : public CObject
{
// ...Member functions
public:
CCompoundObject();
virtual void Serialize( CArchive& ar );

// Implementation
protected:
CMyObject m_myob; // Embedded object
COtherObject* m_pOther; // Object allocated in constructor
CObject* m_pObDyn; // Dynamically allocated object
//..Other member data and implementation

DECLARE_SERIAL( CCompoundObject )
};

IMPLEMENT_SERIAL(CMyObject,CObject,1)
IMPLEMENT_SERIAL(COtherObject,CObject,1)
IMPLEMENT_SERIAL(CCompoundObject,CObject,1)


CCompoundObject::CCompoundObject()
{
m_pOther = new COtherObject; // Exact type known and object already
//allocated.
m_pObDyn = NULL; // Will be allocated in another member function
// if needed, could be a derived class object.
}

void CCompoundObject::Serialize( CArchive& ar )
{
CObject::Serialize( ar ); // Always call base class Serialize.
m_myob.Serialize( ar ); // Call Serialize on embedded member.
m_pOther->Serialize( ar ); // Call Serialize on objects of known exact type.

// Serialize dynamic members and other raw data
if ( ar.IsStoring() )
{
ar << m_pObDyn;
// Store other members
}
else
{
ar >> m_pObDyn; // Polymorphic reconstruction of persistent
// object
//load other members
}
}





RunTimeClass Information Support Example :
====================================


// in .H file
class CPerson : public CObject
{
DECLARE_DYNAMIC( CPerson )
public:
CPerson(){};

// other declaration
};


// in .CPP file
IMPLEMENT_DYNAMIC( CPerson, CObject )


void SomeFunction(void)
{
CObject* pMyObject = new CPerson;

if(pMyObject->IsKindOf( RUNTIME_CLASS( CPerson ) ) )
{
//if IsKindOf is true, then cast is all right
CPerson* pmyPerson = (CPerson*) pMyObject ;
...
delete pmyPerson;
}
...
delete [MyObject];
}


Dynamic Object Creation :
-----------------------------------


To dynamically create an object given its run-time class

Use the following code to dynamically create an object by using the CreateObject function of the CRuntimeClass.
Note that on failure, CreateObject returns NULL instead of raising an exception:

CRuntimeClass* pRuntimeClass = RUNTIME_CLASS( CMyClass );
CObject* pObject = pRuntimeClass->CreateObject();
ASSERT( pObject->IsKindOf( RUNTIME_CLASS( CMyClass ) ) );


Object diagnostic output :
------------------------------------

Dumping Object Contents :

This topic explains how to get a diagnostic dump of the contents ofour objects.

When deriving a class from CObject, we have the option to override the Dump member function and write a textual representation of the object’s member variables to a dump context which is similar to an I/O stream. Like an I/O stream, you can use the insertion (<<) operator to send data to a CDumpContext.

we do not have to override Dump when you derive a class from CObject. However, if we use other diagnostic features for debugging, providing the capability for dumping an object and viewing its contents is very helpful and highly recommended.

Note Before we can dump objects, we must enable diagnostic tracing so we can see the results of our dump in the debugger.


To override the Dump member function

Call the base class version of Dump to dump the contents of a base class object.


Write a textual description and value for each member variable of your derived class.
The declaration of the Dump function in the class declaration looks like:

class CPerson : public CObject
{
public:
#ifdef _DEBUG
virtual void Dump( CDumpContext& dc ) const;
#endif

CString m_firstName;
CString m_lastName;
// etc. ...
};

Note Since object dumping only makes sense when you are debugging your program, the declaration of the Dump function is bracketed with an #ifdef _DEBUG / #endif block.

In the following example from an implementation file for the class CPerson, the Dump function’s first statement calls the Dump member function for its base class. It then writes a short description of each member variable along with the member’s value to the diagnostic stream.

#ifdef _DEBUG
void CPerson::Dump( CDumpContext& dc ) const
{
// call base class function first
CObject::Dump( dc );

// now do the stuff for our specific class
dc << "last name: " << m_lastName << "\n"
<< "first name: " << m_firstName << "\n";
}
#endif

Note Again, notice that the definition of the Dump function is bracketed by #ifdef _DEBUG / #endif directives. If you refer to afxDump in a program linked with the nondebug libraries, you will get unresolved externals errors at link time.

To send Dump output to afxDump

You must supply a CDumpContext argument to specify where the dump output will go when you call the Dump function for an object.
MFC supplies a predefined CDumpContext object named afxDump that you will normally use for routine object dumping.
The following example shows how to use afxDump:

CPerson* pMyPerson = new CPerson;
// set some fields of the CPerson object...
//...
// now dump the contents
#ifdef _DEBUG
pMyPerson->Dump( afxDump );
#endif

In Windows NT, afxDump output is sent to the debugger, if present. Otherwise, you won’t get any afxDump output.

Note afxDump is defined only in the debug version of MFC.

Tuesday, September 11, 2007

Interoperability Tips

Interoperability :

 [DllImport("MAPI32.DLL", CharSet = CharSet.Ansi)]
        public static extern UInt32 MAPISendMail(IntPtr lhSession, IntPtr ulUIParam,
         MapiMessage lpMessage, UInt32 flFlags, UInt32 ulReserved);

 

if we want to rename the MAPISendMail fn  as SendMail within C# , How can we do it ?

we can do the following.

 

    [DllImport("MAPI32.DLL", EntryPoint = "MAPISendMail", CharSet = CharSet.Ansi)]
        public static extern UInt32 SendMail(IntPtr lhSession, IntPtr ulUIParam,
         MapiMessage lpMessage, UInt32 flFlags, UInt32 ulReserved);

 

 EntryPoint = "MAPISendMail"  // specified function address is obtained from the DLL


So In our C# application we can simply call

 SendMail( ...)
 
 
Literally what will happen is the address of the MAPISendMail() fn is assigned to the SendMail() fn.
 
So if we call the SendMail() fn from C#, it will in turn calls the MAPISendMail() functionality from MAPI32.dll
 
 

MAPISendMail in C# Problem

ulResult = MAPI.SendMail(hSession, IntPtr.Zero, message,0, 0);

it works well But if i modified it as follows will not send mail...


ulResult = MAPI.SendMail(hSession, IntPtr.Zero, message,MAPI.MAPI_DIALOG, 0);

MAPISendMail in C# application

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace MAPIConsole
{
/*
[StructLayout(LayoutKind.Sequential)]
public struct MapiRecipDesc
{
public long Reserved;
public long RecipClass;
public string Name;
public string Address;
public long EIDSize;
public object EntryID;
}

[StructLayout(LayoutKind.Sequential)]
public struct MapiMessage
{
public long Reserved;
public string Subject;
public string NoteText;
public string MessageType;
public string DateReceived;
public string ConversationID;
public long Flags;
public object Originator;
public long RecipCount;
public MapiRecipDesc Recips;
public long FileCount;
public object Files;
}
*/


///
/// A MapiFileDesc structure contains information about a file containing a message attachment
/// stored as a temporary file.
///
/// The file can contain a static OLE object, an embedded OLE object, an embedded message,
/// and other types of files.
///

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiFileDesc
{
///
/// Reserved; must be zero.
///

public uint ulReserved = 0;

///
/// Bitmask of attachment flags. Flags are MAPI_OLE and MAPI_OLE_STATIC.
///
/// If neither flag is set, the attachment is treated as a data file.
///

public uint flFlags = 0;

///
/// An integer used to indicate where in the message text to render the attachment.
///
/// Attachments replace the character found at a certain position in the message text.
/// That is, attachments replace the character in the MapiMessage structure field
/// lpszNoteText[nPosition]. A value of – 1 (0xFFFFFFFF) means the attachment position is
/// not indicated; the client application will have to provide a way for the user to
/// access the attachment.
///

public uint nPosition = 0xffffffff;

///
/// Pointer to the fully qualified path of the attached file.
///
/// This path should include the disk drive letter and directory name.
///

public string lpszPathName = string.Empty;

///
/// Pointer to the attachment filename seen by the recipient, which may differ from the filename in
/// the lpszPathName member if temporary files are being used.
///
/// If the lpszFileName member is empty or NULL, the filename from lpszPathName is used.
///

public string lpszFileName = string.Empty;

///
/// Pointer to the attachment file type, which can be represented with a MapiFileTagExt
/// structure.
///
/// A value of NULL indicates an unknown file type or a file type determined by the operating system.
///

public IntPtr lpFileType = IntPtr.Zero;
}

///
/// MapiFileTagExt structure specifies a message attachment's type at its creation
/// and its current form of encoding so that it can be restored to its original type at its destination.
///
/// A MapiFileTagExt structure defines the type of an attached file for purposes such as encoding and
/// decoding the file, choosing the correct application to launch when opening it, or any use that
/// requires full information regarding the file type.
///
/// Client applications can use information in the lpTag and lpEncoding
/// members of this structure to determine what to do with an attachment.
///

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiFileTagExt
{
///
/// Reserved; must be zero.
///

public uint ulReserved = 0;

///
/// The size, in bytes, of the value defined by the lpTag member.
///

public uint cbTag = 0;

///
/// Pointer to an X.400 object identifier indicating the type of the attachment in its original form,
/// for example "Microsoft Excel worksheet".
///

public IntPtr lpTag = IntPtr.Zero;

///
/// The size, in bytes, of the value defined by the lpEncoding member.
///

public uint cbEncoding = 0;

///
/// Pointer to an X.400 object identifier indicating the form in which the attachment is currently
/// encoded, for example MacBinary, UUENCODE, or binary.
///

public IntPtr lpEncoding = IntPtr.Zero;
}

///
/// A MapiMessage structure contains information about a message.
///

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiMessage
{
///
/// Reserved; must be zero.
///

public uint ulReserved = 0;

///
/// Pointer to the text string describing the message subject,
/// typically limited to 256 characters or less.
///
/// If this member is empty or NULL, the user has not entered subject text.
///

public string lpszSubject = string.Empty;

///
/// Pointer to a string containing the message text.
///
/// If this member is empty or NULL, there is no message text.
///

public string lpszNoteText = string.Empty;

///
/// Pointer to a string indicating a non-IPM type of message.
///
/// Client applications can select message types for their non-IPM messages.
///
/// Clients that only support IPM messages can ignore the lpszMessageType member
/// when reading messages and set it to empty or NULL when sending messages.
///

public string lpszMessageType = null;

///
/// Pointer to a string indicating the date when the message was received.
///
/// The format is YYYY/MM/DD HH:MM, using a 24-hour clock.
///

public string lpszDateReceived = DateTime.Now.ToString("yyyy/MM/dd hh:mm");

///
/// Pointer to a string identifying the conversation thread to which the message belongs.
///
/// Some messaging systems can ignore and not return this member.
///

public string lpszConversationID = string.Empty;

///
/// Bitmask of message status flags.
///
/// The flags are MAPI_RECEIPT_REQUESTED , MAPI_SENT,
/// and MAPI_UNREAD.
///

public uint flFlags = 0;

///
/// Pointer to a MapiRecipDesc structure containing information about the
/// sender of the message.
///

public IntPtr lpOriginator = IntPtr.Zero;

///
/// The number of message recipient structures in the array pointed to by the
/// lpRecips member.
///
/// A value of zero indicates no recipients are included.
///

public uint nRecipCount = 0;

///
/// Pointer to an array of MapiRecipDesc structures, each containing
/// information about a message recipient.
///

public IntPtr lpRecips = IntPtr.Zero;

///
/// The number of structures describing file attachments in the array pointed to by the
/// lpFiles member.
///
/// A value of zero indicates no file attachments are included.
///

public uint nFileCount = 0;

///
/// Pointer to an array of MapiFileDesc structures, each containing
/// information about a file attachment.
///

public IntPtr lpFiles = IntPtr.Zero;
}

///
/// A MapiRecipDesc structure contains information about a message sender or recipient.
///

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class MapiRecipDesc
{
///
/// Reserved; must be zero.
///

public uint ulReserved= 0;

///
/// Contains a numeric value that indicates the type of recipient.
///
/// Possible values are:
///
/// Value Constant Meaning
///
/// 0 MAPI_ORIG Indicates the original sender of the message.
/// 1 MAPI_TO Indicates a primary message recipient.
/// 2 MAPI_CC Indicates a recipient of a message copy.
/// 3 MAPI_BCC Indicates a recipient of a blind copy.
///
///

public uint ulRecipClass= MAPI.MAPI_TO;

///
/// Pointer to the display name of the message recipient or sender.
///

public string lpszName = string.Empty;

///
/// Optional pointer to the recipient or sender's address; this address is provider-specific message
/// delivery data. Generally, the messaging system provides such addresses for inbound messages.
///
/// For outbound messages, the lpszAddress member can point to an address entered by the user for
/// a recipient not in an address book (that is, a custom recipient).
///
/// The format of an address pointed to by the lpszAddress member is [address type][e-mail address].
/// Examples of valid addresses are FAX:206-555-1212 and SMTP:M@X.COM.
///

public string lpszAddress = string.Empty;

///
/// The size, in bytes, of the entry identifier pointed to by the lpEntryID member.
///

public uint ulEIDSize = 0;

///
/// Pointer to an opaque entry identifier used by a messaging system service provider to identify the
/// message recipient. Entry identifiers have meaning only for the service provider;
/// client applications will not be able to decipher them. The messaging system uses this member
/// to return valid entry identifiers for all recipients or senders listed in the address book.
///

public IntPtr lpEntryID = IntPtr.Zero;
}



public class MAPI
{

[DllImport("MAPI32.DLL",EntryPoint = "MAPILogon", CharSet = CharSet.Ansi)]
public static extern UInt32 Logon(IntPtr ulUIParam, string lpszProfileName, string lpszPassword,
UInt32 flFlags, UInt32 ulReserved, ref IntPtr lplhSession);



[DllImport("MAPI32.DLL", EntryPoint = "MAPISendMail", CharSet = CharSet.Ansi)]
public static extern UInt32 SendMail(IntPtr lhSession, IntPtr ulUIParam,
MapiMessage lpMessage, UInt32 flFlags, UInt32 ulReserved);


[DllImport("MAPI32.DLL", EntryPoint = "MAPILogoff", CharSet = CharSet.Ansi)]
public static extern uint Logoff(IntPtr lhSession, IntPtr ulUIParam, uint flFlags, uint ulReserved);



public const int SUCCESS_SUCCESS = 0;
public const int MAPI_USER_ABORT = 1;
public const int MAPI_E_USER_ABORT = MAPI_USER_ABORT;
public const int MAPI_E_FAILURE = 2;
public const int MAPI_E_LOGIN_FAILURE = 3;
public const int MAPI_E_LOGON_FAILURE = MAPI_E_LOGIN_FAILURE;
public const int MAPI_E_DISK_FULL = 4;
public const int MAPI_E_INSUFFICIENT_MEMORY = 5;
public const int MAPI_E_BLK_TOO_SMALL = 6;
public const int MAPI_E_TOO_MANY_SESSIONS = 8;
public const int MAPI_E_TOO_MANY_FILES = 9;
public const int MAPI_E_TOO_MANY_RECIPIENTS = 10;
public const int MAPI_E_ATTACHMENT_NOT_FOUND = 11;
public const int MAPI_E_ATTACHMENT_OPEN_FAILURE = 12;
public const int MAPI_E_ATTACHMENT_WRITE_FAILURE = 13;
public const int MAPI_E_UNKNOWN_RECIPIENT = 14;
public const int MAPI_E_BAD_RECIPTYPE = 15;
public const int MAPI_E_NO_MESSAGES = 16;
public const int MAPI_E_INVALID_MESSAGE = 17;
public const int MAPI_E_TEXT_TOO_LARGE = 18;
public const int MAPI_E_INVALID_SESSION = 19;
public const int MAPI_E_TYPE_NOT_SUPPORTED = 20;
public const int MAPI_E_AMBIGUOUS_RECIPIENT = 21;
public const int MAPI_E_AMBIG_RECIP = MAPI_E_AMBIGUOUS_RECIPIENT;
public const int MAPI_E_MESSAGE_IN_USE = 22;
public const int MAPI_E_NETWORK_FAILURE = 23;
public const int MAPI_E_INVALID_EDITFIELDS = 24;
public const int MAPI_E_INVALID_RECIPS = 25;
public const int MAPI_E_NOT_SUPPORTED = 26;
public const int MAPI_ORIG = 0;
public const int MAPI_TO = 1;
public const int MAPI_CC = 2;
public const int MAPI_BCC = 3;
//***********************
// FLAG Declarations
//***********************
//* MAPILogon() flags *
public const int MAPI_LOGON_UI = 0x1;
public const int MAPI_NEW_SESSION = 0x2;
public const int MAPI_FORCE_DOWNLOAD = 0x1000;
//* MAPILogoff() flags *
public const int MAPI_LOGOFF_SHARED = 0x1;
public const int MAPI_LOGOFF_UI = 0x2;
//* MAPISendMail() flags *
public const int MAPI_DIALOG = 0x8;
//* MAPIFindNext() flags *
public const int MAPI_UNREAD_ONLY = 0x20;
public const int MAPI_GUARANTEE_FIFO = 0x100;
//* MAPIReadMail() flags *
public const int MAPI_ENVELOPE_ONLY = 0x40;
public const int MAPI_PEEK = 0x80;
public const int MAPI_BODY_AS_FILE = 0x200;
public const int MAPI_SUPPRESS_ATTACH = 0x800;
//* MAPIDetails() flags *
public const int MAPI_AB_NOMODIFY = 0x400;
//* Attachment flags *
public const int MAPI_OLE = 0x1;
public const int MAPI_OLE_STATIC = 0x2;
//* MapiMessage flags *
public const int MAPI_UNREAD = 0x1;
public const int MAPI_RECEIPT_REQUESTED = 0x2;
public const int MAPI_SENT = 0x4;

}


class Program
{
/*
public void SendMail()
{
uint ulResult = 0;
IntPtr hSession = IntPtr.Zero;
uint ulFlags = MAPI.MAPI_LOGON_UI | MAPI.MAPI_NEW_SESSION;

ulResult = MAPI.Logon(IntPtr.Zero, null, null, ulFlags, 0, ref hSession);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine(" MAPILogon() fn failed...");
return;
}



MapiRecipDesc recipient = new MapiRecipDesc();
recipient.Reserved = 0;
recipient.RecipClass = MAPI.MAPI_TO;
recipient.Name = null;
recipient.Address = "sundararajan_svks@yahoo.com";
recipient.EIDSize = 0;
recipient.EntryID = null;

MapiMessage message = new MapiMessage();
message.Reserved = 0;
message.Subject = "Greetings From C#";
message.NoteText = "Hello Mr...Sundara rajan";
message.MessageType = null;
message.DateReceived = null;
message.ConversationID = null;
message.Flags = 0;
message.Originator = null;
message.RecipCount = 1;
message.Recips = recipient;
message.FileCount = 0;
message.Files = null;


ulResult = MAPI.SendMail(hSession, IntPtr.Zero, ref message, MAPI.MAPI_NEW_SESSION, 0);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine("SendMail() fn failed...");
return;
}

ulResult = MAPI.Logoff(hSession, IntPtr.Zero, 0, 0);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine("Logoff() fn failed...");
return;
}
}
*/

public void SendMail2()
{
uint ulResult = 0;
IntPtr hSession = IntPtr.Zero;
uint ulFlags = MAPI.MAPI_LOGON_UI | MAPI.MAPI_NEW_SESSION;

ulResult = MAPI.Logon(IntPtr.Zero, null, null, 0, 0, ref hSession);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine(" MAPILogon() fn failed...");
return;
}

MapiMessage message = new MapiMessage();
message.lpszSubject = "Greetings From C#";
message.lpszNoteText = "Hello Mr...Sundara rajan";
message.lpOriginator = IntPtr.Zero;//AllocOrigin();
message.nRecipCount = 1;
message.lpRecips = AllocRecips();

ulResult = MAPI.SendMail(hSession, IntPtr.Zero, message,0, 0);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine("SendMail() fn failed...");
return;
}

ulResult = MAPI.Logoff(hSession, IntPtr.Zero, 0, 0);

if (ulResult != MAPI.SUCCESS_SUCCESS)
{
Console.WriteLine("Logoff() fn failed...");
return;
}

Marshal.FreeHGlobal(message.lpRecips);
}

private IntPtr AllocOrigin()
{
MapiRecipDesc recipient = new MapiRecipDesc();
recipient.ulRecipClass = MAPI.MAPI_ORIG;
recipient.lpszName = "sundar";
recipient.lpszAddress = "sundararajan.svks@gmail.com";
recipient.ulEIDSize = 0;
recipient.lpEntryID = IntPtr.Zero;

Type rtype = typeof(MapiRecipDesc);
int rsize = Marshal.SizeOf(rtype);
IntPtr ptrr = Marshal.AllocHGlobal(rsize);

Marshal.StructureToPtr(recipient, ptrr, false);
return ptrr;

}
private IntPtr AllocRecips()
{
MapiRecipDesc recipient = new MapiRecipDesc();
recipient.ulRecipClass = MAPI.MAPI_TO;
recipient.lpszName = "sundararajan";
recipient.lpszAddress = "sundararajan_svks@yahoo.com";
recipient.ulEIDSize = 0;
recipient.lpEntryID = IntPtr.Zero;

Type rtype = typeof(MapiRecipDesc);
int rsize = Marshal.SizeOf(rtype);
IntPtr ptrr = Marshal.AllocHGlobal(rsize);
Marshal.StructureToPtr(recipient, ptrr, false);
//Marshal.PtrToStructure(
return ptrr;


}
static void Main(string[] args)
{

Program p = new Program();
//p.SendMail();
p.SendMail2();
Console.ReadKey();
}
}
}