Wednesday, April 23, 2008

VMware Project North Star Beta (Thinstall)

I really liked this product.check it out!
http://www.vmware.com/beta/northstar/

Saturday, February 23, 2008

MAPI and SMS delivery reports?

Well,Have you ever wanted to Send SMS using MAPI?

Well it is not that hard,you simple call IMessage->SubmitMessage(0);

But what about delivery reports?

Just set these two properties using IMessage->SetProps to true!

PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED
PR_PROOF_OF_DELIVERY_REQUESTED

Here is code snippet ::

props[0].ulPropTag = PR_ORIGINATOR_DELIVERY_REPORT_REQUESTED;
props[0].Value.b = TRUE;

props[1].ulPropTag = PR_PROOF_OF_DELIVERY_REQUESTED;
props[1].Value.b = TRUE;

hr = spMessage->SetProps(2, (LPSPropValue)&props, NULL);

Tuesday, September 25, 2007

SmileySMS and En2FaMail are now v1.53

Well,
Lots of changes happened during past month,and now both applications have plugins for Inbox,so you can also see smiles (and in case of En2FaMail,you Persian text + smilies) in you inbox too!

Hope you enjoyed this program so far!
Here i attached my updated Pictures of these programs.

SmileySMS


En2FaMail

Thursday, September 13, 2007

MAPI : how to delete a message(or move it into trash)?

Well.
I think deleting a message is rather easy,but i find moving a message instead to trash or wastebasket folder is not that easy.
Here is a function i use to determine the wastebasket folder.So i can use IFolder,CopyMessages routine with MAPI_MOVE flag to move my message there!

HRESULT GetWastebasketForFolder(IMAPISession *m_pSession,LPMAPIFOLDER pFolder,
LPMAPIFOLDER* ppfldrWastebasket)
{
HRESULT hr = E_FAIL;
IMsgStore* pms = NULL;
ULONG cItems;
ULONG rgtagsFldr[] = { 1, PR_OWN_STORE_ENTRYID };
ULONG rgtagsMsgStore[] = { 1, PR_IPM_WASTEBASKET_ENTRYID };
LPSPropValue rgprops = NULL;

// This method assumes that the CALLER already logged on to a MAPISession
if (!m_pSession)
CHR(E_FAIL);

// Now request the PR_OWN_STORE_ENTRYID on the folder. This is the
// ENTRYID of the message store that owns the folder object.
hr = pFolder->GetProps((LPSPropTagArray)rgtagsFldr, MAPI_UNICODE, &cItems, &rgprops);
CHR(hr);

CBR(PR_OWN_STORE_ENTRYID == rgprops[0].ulPropTag);

// Now open the message store object.
hr = m_pSession->OpenEntry(rgprops[0].Value.bin.cb,
(LPENTRYID)rgprops[0].Value.bin.lpb,
NULL, 0, NULL, (LPUNKNOWN*)&pms);
CHR(hr);

MAPIFreeBuffer(rgprops);
rgprops = NULL;

// Get the ENTRYID of the wastebasket for the message store
hr = pms->GetProps((LPSPropTagArray)rgtagsMsgStore, MAPI_UNICODE, &cItems, &rgprops);
CHR(hr);

// Now open the correct wastebasket and return it to the caller.
CBR(PR_IPM_WASTEBASKET_ENTRYID == rgprops[0].ulPropTag);

hr = m_pSession->OpenEntry(rgprops[0].Value.bin.cb,
(LPENTRYID)rgprops[0].Value.bin.lpb,
NULL, 0, NULL, (LPUNKNOWN*)ppfldrWastebasket);
CHR(hr);

Error:
MAPIFreeBuffer(rgprops);
RELEASE_OBJ(pms);

return hr;
}



and you call it like this :
GetWastebasketForFolder(pSession,pFolder,&pWasteBasket);


pFolder is a folder where you message is.
And moving is done like this.
pFolder->CopyMessages(&lst, NULL, pWasteBasket, 0, NULL, MAPI_MOVE);


Probably you might know that lst is ENTRYLIST and you construct it like this!
lst.cValues = 1;
sbin.cb = pspvEntryID->Value.bin.cb;
sbin.lpb = (LPBYTE) pspvEntryID->Value.bin.lpb;
lst.lpbin = &sbin;


And pspvEntryID is what i get from calling GetProps to getting this message property ids.

Saturday, September 8, 2007

SmileySMS Program


Well,i removed the Persian/fingilish translations materials from En2FaMail program,and released another program called SmileySMS in xda-developers today.

Here are list of things that this program do:

- Shows and displays smilies found in SMS texts.
- Assign .mp3,.ogg,.wav,.mod and other popular music file formats as your SMS ring tones.
- Remove phone number from the title of SMS notification,when the contact is known.
- Replace number in body of delivery report with the name of contact.
- Show pictures of contacts in SMS notification.
- Easier to use menus for working with SMS notifications.
- WM5.0 like notifications for WM2003 users.
- Support for vibrate.
- All features(including program) are configurable through control panel.

And of course En2FaMail does all these too.

Vibrating your PocketPC device!

How to vibrate a PocketPC WM5.0 or 2003 device?

In smartphone platforms there is a Vibrate API which you can use.
Although MSDN mentioned that it exist in WM5.0,it isn't.
There was a mistake in MSDN documentations.

Searching all over internet I find that there are 2 ways to achieve this.
One way is to use Notify functions like CeSetUserNotificationEx,and setting trigger time to now.
But unless you display a dialog(using PUN_DIALOG),you can't use it and also it seems user settings override your program settings!

Another way is using NLed functions.
Although all people in Google groups and also Microsoft MVPs,mentioned there is no way to know the led number of vibrator,I find out when you use NLedGetDeviceInfo on a Led slot,and the lCycleAdjust is -1, it is your device vibrator's led number!


Here is the code I've written to use vibrate of my device!
I also checked it on some other devices and they all worked!

void LedOn(int id)
{
NLED_SETTINGS_INFO settings;
if (id < 0)
return;
settings.LedNum= id;
settings.OffOnBlink= 1;
NLedSetDevice(NLED_SETTINGS_INFO_ID, &settings);
}

void LedOff(int id)
{
NLED_SETTINGS_INFO settings;
if (id < 0)
return;
settings.LedNum= id;
settings.OffOnBlink= 0;
NLedSetDevice(NLED_SETTINGS_INFO_ID, &settings);
}

int GetVibratorLedNum(void)//-1 means no vibrator
{
NLED_COUNT_INFO nci;
int wCount = 0,VibrLed = -1;
NLED_SUPPORTS_INFO sup;

if(NLedGetDeviceInfo(NLED_COUNT_INFO_ID, (PVOID) &nci))
wCount = (int) nci.cLeds;

for (int i=0;i<wCount;i++)
{
sup.LedNum = i;
NLedGetDeviceInfo(NLED_SUPPORTS_INFO_ID,&sup);
if (sup.lCycleAdjust == -1)
{
VibrLed = i;
break;
}
}
return VibrLed;
}- param1 + 1



You also need to add these to your source files!


#include
extern "C" {
BOOL WINAPI NLedGetDeviceInfo( UINT nInfoId, void *pOutput );
BOOL WINAPI NLedSetDevice( UINT nDeviceId, void *pInput );
};



Also note that most PocketPcs do not support vibrators,mostly PocketPc Phone editions do.

Thursday, August 30, 2007

How to debug your Control Panel Application(or applet) in Windows Mobile Devices?

How to debug Control Panel Applets in Pocket PC 2003 and Pocket PC 5.0 devices?

Recently while developing my En2FaMail control panel program i came into this problem.
Reading MSDN documentations and searching Internet,you will find you have to use ctlpnl.exe as your host program.But this doesn't seem to work.

Anyway before beginning,a short introduction to Control Panel Applets!

Control Panel Applets are basically dll files but with extension of cpl.And they have to export a function like this.

LONG CALLBACK CPlApplet (HWND hwndCPL, UINT uMsg, LONG lParam1, LONG lParam2)

And windows send following messages to communicate with this applet

CPL_GETCOUNT
CPL_INIT
CPL_NEWINQUIRE
CPL_STOP

There is also a sample in PocketPc 5.0(and i guess also PocketPc 2003) SDKS,name MyBacklight.

Also you can read following pages for more information on how to develop your own Control Panel Applets.
An Ancient Story of Control Panel Applets
Using Control Panel

So how to debug your program?

As Control Panel Applets are dll files they need a host,so to function and also for you to debug them.
I find out you can use mstli.exe as your host application.You have to set \windows\mstli.exe as your host in visual studio debugging page.
But if mstli.exe was ran for any reasons,first you have to kill this task.Eighter by visual studio or your own task manager in your PocketPc.(You cant use default memory control panel applet to kill this task,as it is not shown there).

After deploying and running,you also have to manually start your program,by going into settings and tapping on your application name.
Also it seems you have to do it not very slowly,as visual studio again terminates the task.

And then you are good to go!

Saturday, August 25, 2007

Uniscribe and Delphi!

Microsoft has an extremely powerful API called Uniscribe that allows applications to do typography of scripts.Things that are mostly in interest of those who wants to make their programs multilanguage.

ut, one big problem with Uniscribe is the lack of samples and documentations over internet.

Problem :
I have a routine in my En2Fa library that gives me a widestring.If this WideString is displayed in right to left TLabel or TEditBox(i.e., in Delphi a component with BIDI set to right-to-left),you can see that it is displayed correctly.(You wont see the difference until you have both English and Persian-in my case-or both RTL and LTR texts in your string).
But if you display it in a window that doesn't have RTL attribute, some swapping of words will be noticed.
I wanted to use Uniscribe to fix this problem.

But why?

Well in my Y!En2FaMsngr program, I have to output this text into Yahoo Messenger editbox, and reading it correctly is not also an issue, but sending it correctly is more important.
So i have to reorder the text that it both displays ok and also sends to other party in correct way.
Making Yahoo Messenger edit box right to left is not a problem. You can use this code to make edit boxes right to left.

lAlgn := GetWindowLong(hYahooEditHnd, GWL_EXSTYLE) ;

// To toggle alignment and reading order
lAlgn := lAlgn or WS_EX_RIGHT or WS_EX_RTLREADING;

SetWindowLong(hYahooEditHnd, GWL_EXSTYLE, lAlgn );
InvalidateRect(hYahooEditHnd, nil, false);


Searching over internet, and also looking at Uniscribe documentation in your SDK you will notice there are several functions that will do the job of displaying texts, but what I need is a logical form of reordered string. So I can use normal WM_SETTEXT to set text of yahoo EditBox.

Logical order is an order that you typed your strings. But visual order is how text should be displayed.
Look here how logical and visual orders are different.
So, I created ApplyRightToLeft function that tries to reorder logical string so it can be displayed ok in left to right EditBox.

To start you need Uniscribe Delphi unit files. You can download it from here.
Two important functions I used are ScriptItemize and ScriptLayout.

Look at the code below.

function ApplyRightToLeft(inText:WideString) : WideString;
type
SCRIPT_ITEMArray = array of SCRIPT_ITEM;
var
items:SCRIPT_ITEMArray;
control : SCRIPT_CONTROL;
state : SCRIPT_STATE;
generated_items,max_items : integer;
hr : HRESULT;
text_len,i : integer;
bidiLevel:array of byte;
LogicalToVisual ,VisualToLogical :array of integer;
widths:array of integer;
begin
Result := '';
text_len := Length(inText);
if text_len = 0 then
exit;
// Most applications won’t need to set any control flags.
ZeroMemory(@control, sizeof(SCRIPT_CONTROL));

// Initial state, you will probably want to keep this updated as you process
// runs in order so that you can always give it the correct direction of the
// surrounding text.
ZeroMemory(@state, sizeof(SCRIPT_STATE));
state.uBidiLevel := 0; // 0 means that the surrounding text is left-to-right.

max_items := 16;
while (true) do
begin
// Make enough room for the output.
SetLength(items,max_items);

// We subtract one from max_items to work around a buffer overflow on some
// older versions of Windows.
generated_items := 0;
hr := ScriptItemize(PWideChar(inText), text_len, max_items - 1, @control,
@state, @items[0], @generated_items);
if (SUCCEEDED(hr)) then
begin
// It generated some items, so resize the array. Note that we add
// one to account for the magic last item.
SetLength(items,generated_items + 1);
break;
end
else
if (hr <> E_OUTOFMEMORY) then
begin
// Some kind of error.
exit;
end;

// The input array isn't big enough, double and loop again.
max_items := max_items*2;
end;

SetLength(bidiLevel,generated_items);
SetLength(VisualToLogical ,generated_items);
SetLength(LogicalToVisual ,generated_items);

// Manually extract bidi-embedding-levels ready for ScriptLayout
for i := 0 to generated_items-1 do
bidiLevel[i] := items[i].a.s.uBidiLevel;

// Build a visual-to-logical mapping order
ScriptLayout(generated_items, @bidiLevel[0], @VisualToLogical [0],@LogicalToVisual [0]);

SetLength(widths,high(items)+1);
for I := 0 to high(items) do
items[i].iCharPos := items[i].iCharPos + 1;

for I := 0 to high(items) - 1 do
widths[i]:=items[i+1].iCharPos - items[i].iCharPos;
widths[high(items) ]:=1;

for I := generated_items - 1 downto 0 do
Result:=Result+copy(inText,items[VisualToLogical[i]].iCharPos,
widths[VisualToLogical[i]]);

// free the temporary BYTE[] buffer
bidiLevel := nil;
VisualToLogical := nil;
LogicalToVisual := nil;
widths := nil;
items := nil;
end;


The job of ScriptItemize is to break a Unicode string into individually shapeable items and giving you SCRIPT_ITEM structures representing the items that have been processed.
Look at the result of ScriptItemize with following text.

And here is how it is formed in logical order.

So in my function generated_items will be 3.
After that things are easy, you have to calculate width of each run, and using ScriptLayout that gives you Logical to Visual table-which gives you an array showing which runs should be displayed first-.And showing it in reverse order is all you have to do.

Here are links that can make life a little bit easier when using Uniscribe.
Uniscribe
Unicode Script Processor for Complex Scripts
Supporting Multilanguage Text Layout and Complex Scripts with Windows NT 5.0
Design and Implementation of a Win32 Text Editor
Displaying Text with Uniscribe
Globalization Step-by-Step
Limitations of Uniscribe
Supporting multilanguage text layout and complex scripts with Windows 2000
Yes I know, I hate VB but...just for those interested
Tutorial Using Unicode in Visual Basic 6.0

Wednesday, August 22, 2007

Intresting Site.

Well,i was just wondering how could i play midi files on PocketPcs.
So far it seems to be a complicated process,Or i didn't quite get it.

I am using FMODCE for my application,but unfortunately it doesn't support midi files.Long ago i used SDL + timidity for my Duke Nukem game to play midi files.
But well i really don't like the idea of shipping 30mg instrument files with my application.Seems the ArcSoft hast it,but not for free!

Anyway i ran into this interesting site,with a little bit strange,long name.

http://www.ifihadadollarforeverytimesomeonesaidthatiwouldhavemyownwebsite.com

Blogger filtered?

Well,but why only first page of it,and login page is censored?
Also comments are censored too.
It is really a pain to post in blogger.You have to use tor and login,then you can normally do the rest.
I think maybe Iranian weblog providers prefer to use theirs instead of Google,i see no other reason for blocking main page of blogger!

Monday, August 20, 2007

Have you ever used Lazarus for Pocket PC development?

Well,i really don't know why still people are not -that much- using Lazarus + FPC for Pocket PC development.

I think the main problem is,it is not well advertised,and lots of people don't know about it yet.
Another factor could be that it is an open source software,and well people sometimes have some wrong ideas about open source software in general,like being unstable,not good looking and so on.

Anyway,i really think the best option for object pascal programmers is Lazarus + FPC for Pocket Pc development.
I really think it is also best choice for other developers trying to develop in win32.Don't you really hate C strings?MFC?ATL?
I know c/c++ really well,but being a long time turbo pascal and afterwards Delphi user,i really couldn't get the idea behind MFC and ATL.
It just don't work for me.


Here is list of my cons and pros.

Pros :
1- It feels like a really big,full featured,stable IDE environment and just looks like good Delphi 7.
2- Your programs will be based on LCL widget set which you can whenever you want simply migrate your program to Win32/Linux/Mac OS environments.
3- It is pascal/Delphi language.If you are familiar with VCL and Delphi.Everything here is the same.
4- You also have a good debugger.So debugging your programs in your retail device or also in emulators is piece of cake.
5- Lots and Lots of components and sources are available in Internet,you simply need to compile them for ARM/Pocket PC target.
6- Results are in native machine instructions,not in slow .net or java platforms.And no need that users installed these into their machines.

Cons
1- .exe files are bigger in comparison to what visual studio produces.But you can always safely use UPX or even switch into using KOL for your widgetset based programs.(look at kol-ce for sources).

Just that.I really see no other problem with current implementation of Lazarus and FPC.

Not to mention that my En2FaMail program is also compiled with FPC.based on my long time ago En2Fa program sources.
At first i tried to use Delphi 2005 .net cf implementations.
but when i just saw that much of errors on you can not use pointers and...
I abandoned the project.

Anyway,here is the screenshot i created when i was implementing LCL for wince just to convince anybody that everything was working.


And LCL has improved a lot since then.
I hope i convinced some of you in how great could be development with LCL.Especially for those who are still using pure c for their programs,and those who hate .net!!

For more information please look at these URLs :
http://wiki.lazarus.freepascal.org/Windows_CE_Interface
http://wiki.lazarus.freepascal.org/Windows_CE_Development_Notes
http://wiki.freepascal.org/WinCE_port

Y!En2FaMsngr Program or (Yahoo Messenger + En2Fa) or How not use fingilish in Yahoo Messenger program



Sometimes i wonder,when all this En2Fa*s will end.
I guess NEVER.

Anyway,this is again my En2Fa program for your Yahoo Messenger.
This program convert/translate all your incoming messages(which are mostly in fingilish - pinglish) into Persian.
Very easy to use.
Also no problem if your messages are too in Persian,program simple ignores them and displays them OK.

You can grab the program from here.

From programming side of things,I simply injected a dll into Yahoo Messenger,and also some html injection to,and not to forget that I've had to create an Activex module too.
It really took sometime from me,but worth it.

Hope i can discuss it with you soon.