Friday, August 29, 2008

What does DTM_BROWSERDISPATCH gives you?

Well,as some documentations state it gives you IBrowser,IBrowser2,IBrowser3 interfaces.
Remember they are different from IWebBrowser and IWebBrowser2 interfaces.
But where are the definitions of these interfaces?
Well actually from win ce 4.2,there are no such interfaces found in your SDK.So you have to use older SDKs found in for example PocketPC 2000/2002,and copy/paste them into your header file.
Unfortunately Microsoft also uses another interface to negotiate with HTML Document viewer,which there is no documentation for it.Interace GUID is {698e3fcb-70c3-11d0-81e8-00a0c90ad20a} but so far i haven't find any documentation for it.

But why do i need all these?
The problem is with Images.With use of DTM_SETIMAGE you can only give HTML Viewer a handle to your bitmap.The problem is i want to display it as transparent bitmap and so far i haven't find any way.
And tracing DTM_SETIMAGE,it gives these information to that undocumented interface.So i still don't know how can i use HTML Viewer with transparent images.

Wednesday, August 20, 2008

Why there is no information on....?

Why there is no information anywhere on BI_FOURCC ?
Why there is no information anywhere on BI_ALPHABITS ?
Why there is no information on 32 bit Bitmaps?
Why there is no information anywhere on How to embed OLE Browser on your application?
Why there is no information on How to use Memory bitmaps inside your OLE Browser?
Why there is no information on RIL interfaces?
Why there is no information on How to send SMS using RIL?
And why Windows Mobile development requires this much of undocumented information?
And Why Microsoft's own applications completely use different set of unnamed/undocumented APIs?

Well,actually i am really angry,but hey,i managed to find some information on some of questions above.
Hope i can share them with you.

Thursday, August 7, 2008

PocketPC Threaded Messaging (SMS) for everyone!

Microsoft added threaded messaging in WM6.1 but there is no way to use threaded messaging on earlier versions of windows mobile like wm5 and wm6.

But things have changed now!

SmileySMS can bring threaded messaging to wm5,wm6 devices and also to wm6.1 devices with support for smileys!

Here is the nice and sexy screenshot of newer versions of SmileySMS.

How do you know SMS belong to which folder in MAPI?

Well,somethimes you might want to know that this SMS is in which folder,for example in Drafts folder,in Inbox folder or...?
A quick not is that never rely on results from PR_DISPLAY_NAME because names like "Inbox","Drafts Folder" can be localized.
Here is the code snippet i use.
You have to use it like this.

if (isFolderTypeSame(pSession,pFolder,PR_CE_IPM_INBOX_ENTRYID))

You can use these values for third parameter.
PR_CE_IPM_DRAFTS_ENTRYID
CE_IPM_INBOX_ENTRYID
PR_IPM_OUTBOX_ENTRYID
PR_IPM_WASTEBASKET_ENTRYID
PR_IPM_SENTMAIL_ENTRYID


bool isFolderTypeSame(IMAPISession *m_pSession,LPMAPIFOLDER pFolder,ULONG _PR_FOLDERTYPE)
{
HRESULT hr = E_FAIL;
CComPtr<IMsgStore> pms ;
ULONG cItems;
SizedSPropTagArray(2, rgtagsFldr) = {2 , PR_OWN_STORE_ENTRYID,PR_ENTRYID};
ULONG entryid[] = { 1, _PR_FOLDERTYPE };
LPSPropValue fldrprops=NULL,msgstoreprops = NULL;
ULONG result=0;

// 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((SPropTagArray *) &rgtagsFldr, MAPI_UNICODE, &cItems, &fldrprops);
CHR(hr);


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


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


m_pSession->CompareEntryIDs(fldrprops[1].Value.bin.cb,(LPENTRYID)fldrprops[1].Value.bin.lpb,msgstoreprops[0].Value.bin.cb,(LPENTRYID)msgstoreprops[0].Value.bin.lpb,0,&result);

Error:
MAPIFreeBuffer(msgstoreprops);
MAPIFreeBuffer(fldrprops);
return result;
}

How to create and send SMS using MAPI?

Here is a code snippet i use to create and send my SMS in SmileySMS program.
From my experience,using fewer properties for ModifyRecipients or SetProps will make it fail on some devices.

IMsgStore *FindInboxSMSStore(IMAPISession *pSession)
{
const SizedSPropTagArray (2, spta) = { 2, PR_DISPLAY_NAME, PR_ENTRYID };
HRESULT hr;
SRowSet *prowset = NULL;
CComPtr<IMAPITable> ptbl;
CComPtr<IMsgStore> pStore;

// Get the table of accounts
hr = pSession->GetMsgStoresTable(0, &ptbl);
CHR(hr);
// set the columns of the table we will query
hr = ptbl->SetColumns((SPropTagArray *) &spta, 0);
CHR(hr);

while (TRUE)
{
hr = ptbl->QueryRows (1, 0, &prowset);
if ((hr != S_OK) || (prowset == NULL) || (prowset->cRows == 0))
break;

ASSERT (prowset->aRow[0].cValues == spta.cValues);
SPropValue *pval = prowset->aRow[0].lpProps;

ASSERT (pval[0].ulPropTag == PR_DISPLAY_NAME);
ASSERT (pval[1].ulPropTag == PR_ENTRYID);

if (!_tcscmp(pval[0].Value.lpszW, TEXT("SMS")))
{
// Get the Message Store pointer
hr = pSession->OpenMsgStore(0, pval[1].Value.bin.cb, (LPENTRYID)pval[1].Value.bin.lpb, 0, 0, &pStore);
CHR(hr);
FreeProws (prowset);

return pStore;
}
// Free the previous row
FreeProws (prowset);
prowset = NULL;
}
Error:
FreeProws (prowset);
return NULL;
}



HRESULT CreateSendSMSMessage(IMAPISession *spSession,LPCTSTR lpszToNumber, LPCTSTR lpszToDisplay,LPCTSTR lpszMessage,IMessage** pMsg)
{
CComPtr<IMsgStore> spMsgStore;
ULONG cItems;
ULONG rgtagsMsgStore[] = { 1, PR_CE_IPM_DRAFTS_ENTRYID };
LPSPropValue rgprops;
HRESULT hr;

spMsgStore = FindInboxSMSStore(spSession);
if (spMsgStore == NULL)
return S_FALSE;

CComPtr<IMAPIFolder> spFolder;

hr = spMsgStore->GetProps((LPSPropTagArray)rgtagsMsgStore, MAPI_UNICODE, &cItems, &rgprops);
if (FAILED(hr))
return hr;

hr = spSession->OpenEntry(rgprops[0].Value.bin.cb,(LPENTRYID)rgprops[0].Value.bin.lpb,
NULL, 0, NULL, (LPUNKNOWN*)&spFolder);
if (FAILED(hr))
return hr;

MAPIFreeBuffer(rgprops);

hr = spFolder->CreateMessage(NULL, 0 ,&(*pMsg));
if (FAILED(hr))
return hr;

int cb;
LPSRowSet pRowSet = NULL;
LPSPropValue pVal = NULL;
LPBYTE pb = NULL;

// * 5 because there are 5 props
cb = sizeof(SRowSet) + sizeof(SPropValue) * 5; // SRowSet includes one SRow.

// Now allocate a buffer.
CPR((pb = new BYTE[cb]))

// Copy the properties over.
pRowSet = (LPSRowSet)pb;
pVal = (LPSPropValue)(pb + ( sizeof(SRowSet) + sizeof(SRow) ));

// initialize
pRowSet->aRow[0].cValues = 0;
pRowSet->aRow[0].lpProps = pVal;

// begin filling the values
pVal->ulPropTag = PR_RECIPIENT_TYPE;
pVal->Value.ul = MAPI_TO;
++pVal;
++pRowSet->aRow[0].cValues;

pVal->ulPropTag = PR_EMAIL_ADDRESS;
pVal->Value.lpszW = (LPWSTR)lpszToNumber;
++pVal;
++pRowSet->aRow[0].cValues;

pVal->ulPropTag = PR_DISPLAY_NAME;
pVal->Value.lpszW = (LPWSTR)lpszToDisplay;
++pVal;
++pRowSet->aRow[0].cValues;

pVal->ulPropTag = PR_ADDRTYPE;
pVal->Value.lpszW = L"SMS";
++pVal;
++pRowSet->aRow[0].cValues;

pVal->ulPropTag = PR_MESSAGE_CLASS;
pVal->Value.lpszW = (LPTSTR)L"IPM.SMStext";
++pVal;
++pRowSet->aRow[0].cValues;

pRowSet->cRows = 1;

hr = (*pMsg)->ModifyRecipients(MODRECIP_ADD, (LPADRLIST)pRowSet);
CHR(hr);

// now we set the additional properties for the
// message
SPropValue props[6];

ZeroMemory(&props, sizeof(props));

// first set the subject of the message
// as the sms we are going to send
props[0].ulPropTag = PR_SUBJECT;
props[0].Value.lpszW = (LPWSTR)lpszMessage;

props[1].ulPropTag = PR_MSG_STATUS;
props[1].Value.ul = MSGSTATUS_RECTYPE_SMS;

props[2].ulPropTag = PR_SENDER_ADDRTYPE;
props[2].Value.lpszW = L"SMS";

props[3].ulPropTag = PR_MESSAGE_CLASS;
props[3].Value.lpszW = L"IPM.SMStext";

props[4].ulPropTag = PR_MESSAGE_FLAGS;
props[4].Value.ul = MSGFLAG_FROMME | MSGFLAG_UNSENT;

props[5].ulPropTag = PR_SENDER_EMAIL_ADDRESS;
props[5].Value.lpszW = (LPWSTR)lpszToNumber;

hr = (*pMsg)->SetProps(sizeof(props) / sizeof(props[0]), (LPSPropValue)&props, NULL);
if (FAILED(hr))
return hr;

(*pMsg)->SaveChanges(0);
// having set all the required fields we can now
// pass the message over to the msgstore transport
// to be delivered.
//hr = (*pMsg)->SubmitMessage(0);
//if (FAILED(hr))
//return hr;
Error:
delete [] pb;
return FALSE;
}

Monday, July 7, 2008

3D AltTab



Well,here is another program of mine.
This program rotates between current running applications.
For using it,i recommend assigning a hardware key to it and use it to rotate your device.



Here is a video clip posted on youtube,demonstrating program.

You can download it from here.

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.

Sunday, August 19, 2007

En2Fa



Well,i know it might be old.The program i mean.
But becouse i lost my site,maybe putting it againg here in my blog will help peaple using google search to find a software that translate/convert fingilish/pingilish/pengilish words or sentences into very good and readable persian/farsi.

You can find always find out more with some googling.
I bet you wont find anything better than this software,besides it is only 500kb.Worth downloading.

Here is my En2Fa program.

Saturday, August 18, 2007

my En2FaMail program.



This is my En2Fa program for Pocket PC Phones.
You can grab it from here.

I think it is mostly for use of people living in Iran,But other Persian talking people can also benefit from this program.

As my main program,En2Fa this program Converts fingilish/pingilish typing into readable Persian language.
Pingilish or fingilish is kind of language,simply invented because of problems with no available Persian fonts or Persian keyboard.
You can find the definition from wikipedia like this (well actually i created that page :) ):

"Fingilish (Farsi + English) (also Penglish or Pinglish, Finglish, Pingilish and Fārgilisi) is a term used to describe the way Persian words are written in Latin alphabet. This type of writing is commonly used in online chat, emails and SMS."

So this program simply do the hard job of translating fingilish into persian.

But what is En2FaMail?

It translates your SMSs into Persian.And the interesting -and for me real hard-part is you really do not need to install any special font,or Arabic/Persian language program to being able to read Persian.
En2FaMail takes care of everything.
Also you can set special sounds in formats like .mp3,.ogg or .mod to your incoming SMSs.

Also side notes are that,this program can be easily disabled from control panel(settings) of your device.
And does not change your SMSs in inbox,simply displays them in Persian.
So feel free to use it and also recommend it to others.

Some features of this program :

- Changing your fingilish/pinglish SMSs into Persian/Farsi language.
- All settings can be changed from control panel(Pocket PC settings)
- No need for Persian/Arabic Making softwares,like Arabizer.
- You can view Persian incoming SMSs in systems without Persian font and Arabic/Persian making software.
- All original SMS features like,Save as read,reply,call sender is implemented.
- All SMS text is viewed in notification,for bigger SMSs scroll bars will appear so you can scroll and real your SMS
- Delivery reports are fixed.So there will be no more numbers in your delivery reports,but Contact names will be replaced.
- Persian Delivery report texts also exist.
- You can assign notification sounds in formats of .mp3,.mod,.mid,.ogg,.wav to your incoming SMSs
- And many more....


But hey this is a programming weblog,So
I will be starting my MAPI and some other lessons soon.All regarding this software.
Actually i find many interesting things to say.
Hope in this week or next week i can post something about Inbox Mail Rules and...