Code Repo    |     RSS
MD's Technical Sharing



Sunday, March 29, 2009

Cookies in ASP, ASP.NET and JavaScript

Cookies are used to track website visitors and retain user preferences. Consider the following code:

<%
Response.Cookies("SweetCookie") = "true"
Response.Cookies("SweetCookie").Expires="December 31, 2004"
%>


The code above creates a cookie called SweetCookie on the user's computer. The cookie is set to expire at the end of 2004. If you want your cookie to expire when your visitor closes his browser, all you need to do is NOT to set the Expires property of Response.Cookies.

Reading cookies in ASP is as easier as writing them

<%
sCookie = Request.Cookies("SweetCookie")
%>


You can use cookies to determine if a visitor has been on your website before (returning visitor), and display customized greeting message depending on that:

<%
If Request.Cookies("SweetCookie") = "true" Then
sResponse = "Welcome returning visitor!"
Else
sResponse = "Welcome new visitor!"
Response.Cookies("SweetCookie") = "true"
Response.Cookies("SweetCookie").Expires="December 31, 2004"
End If

Response.Write sResponse
%>


Similiarly in ASP.NET, you can add cookies to the System.Web.HttpResponse.Cookies collection similar to the following example:

Response.Cookies("userName").Value = "patrick"
Response.Cookies("userName").Expires = DateTime.Now.AddDays(1)

Dim aCookie As New HttpCookie("lastVisit")
aCookie.Value = DateTime.Now.ToString()
aCookie.Expires = DateTime.Now.AddDays(1)
Response.Cookies.Add(aCookie)


In Javascript, cookies can be created, read and erased by JavaScript. They are accessible through the property document.cookie. Though you can treat document.cookie as if it's a string, it isn't really, and you have only access to the name-value pairs.

document.cookie =
'ppkcookie1=testcookie; expires=Thu, 2 Aug 2001 20:47:11 UTC; path=/';


To make things easier, we need the following functions to have full access to cookie:

function createCookie(name,value,days) {
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}

function eraseCookie(name) {
createCookie(name,"",-1);
}
Read More »

Allow user to expand/collapse blocks of text on a web page

You've seen expand/collapse blocks just about everywhere on the Internet! Ever wanted to know how to make your own? You'll be surprised at how simple it is - just a few lines of JavaScript will let you toggle any block of content on your webpage.

Let us start with a simple block of text (it could as well contain images and any other content) that we wish to make toggle-able:

<div id="content">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nunc fermentum.
</div>

Next, we add a link that toggles the block when clicked:

<a href="#" onclick="toggle('content')">Toggle</a>


All that is left is the actual toggle function. The toggle function itself is quite simple: it takes the ID of the element to toggle and uses the CSS display property to show/hide it. By default, the display property is blank. (unless specified otherwise in the CSS) To hide an element, you just set display to 'none'. The code goes like this:

<script type="text/javascript">
function toggle(id) {
var e = document.getElementById(id);

if (e.style.display == '')
e.style.display = 'none';
else
e.style.display = '';
}
</script>


Put the above 3 code fragments together and you've got a working expand/collapse block.

In the above example, the block is initially visible. To have the block hidden by default, simply modify the first line as follows:

<div id="content" style="display:none">

Reference:
http://www.ozzu.com/javascript-tutorials/tutorial-expand-collapse-blocks-and-navigation-trees-t89202.html
Read More »

Tuesday, March 24, 2009

Enumerate through all files in a folder

This can be achieved easily using the Win32 APIs FindFirstFile and FindNextFile


WIN32_FIND_DATAW FindFileData;

//find the first file matching the pattern

HANDLE hFind = FindFirstFile(L"\\My Documents\\*.jpg", &FindFileData);

//find the first file, continue to find next file

if (hFind != INVALID_HANDLE_VALUE)

{

printf("%S", FindFileData.cFileName);

while (FindNextFile(hFind, &FindFileData) != 0)

{

}

FindClose(hFind);

}

Read More »

Friday, March 20, 2009

Convert MHT into HTML

You can change the file extension on the file from ".mht" to read ".uue". You can then open the ".uue" file up in a zip program such as WinZip.

You can then extract one or all the files contained in the renamed .mht file using the WinZip program interface.

Of course, you will have to change the file extensions on the extractedfiles because the extracted .html file will have a .txt file extension when extracted. For instance, when you are viewing the .uue file in WinZip the.html file will have the name 0001.txt and will also have that name and extension when it's extracted. So once it's extracted just change the name of the file from 0001.txt to myfile.html for example. Likewise, image files contained in the .uue file will contain extensions such as .001, 002, etc... and will have to be renamed with thier proper extension once they've been extracted.


You can also rename the extension to EML and view as an email with Outlook Express. Alternatively, use Universal Extractor which uses ExtractMHT.


Reference: http://www.eggheadcafe.com/conversation.aspx?messageid=31490544&threadid=31490538


Read More »

Thursday, March 19, 2009

Open a file with its default viewer:

The following will open a file with its default viewer. The behaviour is exactly the same as what will happen when you double click on that file in Explorer.

SHELLEXECUTEINFO lpExecInfo;
memset(&lpExecInfo, 0, sizeof(SHELLEXECUTEINFO));
lpExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
//name of file to open. For URL, it will be open in the default browser
lpExecInfo.lpFile = L"doc1.doc";
lpExecInfo.lpParameters = _T("");
lpExecInfo.lpDirectory = _T("");
lpExecInfo.lpVerb = _T("open");
lpExecInfo.fMask = 0;
lpExecInfo.hwnd = g_hwnd; //handle of current window
lpExecInfo.hInstApp = g_hinstModule; //handle to current executable
if (!ShellExecuteEx(&lpExecInfo))
{
//cannot run, show error here
}

Alternatively, use the following to use any program to open a particular file:

PROCESS_INFORMATION pi = {0};
if (!CreateProcess(L"notepad.exe", L"readme.txt", NULL, NULL, NULL, 0, NULL, NULL, NULL, &pi))
printf("Cannot execute process \n");
else
WaitForSingleObject(pi.hProcess, INFINITE);

Read More »

Monday, March 16, 2009

Use the DefaultEvent attribute in .NET

The DefaultEvent attribute indicates a class's default event. If the class is a component and you double-click on it in a form, the code editor opens to this event.

VB.NET:
<DefaultEvent("Reorg")> _
Public Class Organization
Public Event Reorg()
End Class


C#:

[DefaultEvent("Reorg")]
public class Organization
{
….
}

Reference:

www.vb-helper.com/howto_net_default_event.html
Read More »

Saturday, March 14, 2009

Allow only digits in textbox

The following code apply ES_NUMBER to allow only digits to be typed into the edit control.


Public Const GWL_STYLE As Int32 = (-16)
Public Const ES_NUMBER As Int32 = &H2000


<DllImport("User32.dll", EntryPoint:="GetWindowLong")> _
Public Function GetWindowLong(ByVal window As IntPtr, ByVal index As Int32) As Int32
End Function


<DllImport("User32.dll", EntryPoint:="GetWindowLong")> _
Public Function SetWindowLong(ByVal window As IntPtr, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32
End Function

'accept only digit in the specified textbox
Public Sub SetNumericInputMode(ByVal txtBox As TextBox)
Dim style As Int32 = GetWindowLong(txtBox.Handle, GWL_STYLE)
SetWindowLong(txtBox.Handle, GWL_STYLE, style
Or ES_NUMBER)
End Sub

Read More »

Thursday, March 12, 2009

Debug TodayScreenPlugin/HomeScreenPlugin

For PocketPC, make sure your today screen item is visible on the device and it is using the latest build so the debug files match up with the executable. Go to the Debug Menu, and choose "Attach to Process..." Change the Transport line from Default to Smart Device. Change the Qualifier drop down to the type of device you are using. If you haven't selected any devices lately you'll have to click the browse button and manually select your device type.


You'll see a list of processes running on your handheld, but only EXE processes can be attached to. Shell32 is the process that loads the today screen. If you are viewing the today screen it should say "Desktop" for the title.


Select the shell32.exe process and click Attach. Set a break point in the WM_PAINT handler of your today item click the start menu on the device. You should catch the WM_PAINT message the today menu invalidates your today item causing a refresh/redraw.


To debug a Home Screen Plugin (Smartphone) at runtime, you must attach the debugger to the home.exe process.


References:

1. http://russryba.vox.com/library/post/debugging-today-screen-items-in-visual-studio-2005.html

2. http://msdn.microsoft.com/en-us/library/aa455227.aspx

Read More »

Monday, March 9, 2009

Disable full-screen edit mode in smartphone's multiline textbox

The multi-line textbox created by .NET CF on a smartphone does not allow inline editing. As soon as user presses ENTER, the textbox enters full-screen edit mode, and editing must be done there.


To understand what is going on here, we need to understand into native code. The textbox control in .NET CF is a wrapper around the native edit control, however the specific wrapping which occurs changes depending upon the value of the multiline property.


As the "Expandable Edit Controls" article available on MSDN documents (available at http://msdn2.microsoft.com/en-us/library/ms911985.aspx), to get an expandable edit control in native Win32 code requires two controls to be constructed. A normal edit control, followed by a up down spinner control. It is the spinner control that is drawing the arrow to the right hand edge of the textbox control and introducing the behaviour which enables bringing up a fullscreen edit window. The .NET Compact Framework is hiding this additional control/complexity by automatically creating the required controls whenever the multiline property is changed.


There doesn't appear to be a property or method exposed via the Compact Framework which will enable the user to decide how multiline text box controls should be handled.


Knowing this and by using a tool such as Remote Win Spy++ to see what is going on at the OS level, the following hack attempts to remove the spinner control and disable the ENTER key to prevent the textbox entering into full-screen edit mode


using System.Runtime.InteropServices;


[DllImport("coredll.dll")]

private static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);


private const int GW_HWNDNEXT = 2;


[DllImport("coredll.dll")]

private static extern IntPtr GetParent(IntPtr hWnd);


[DllImport("coredll.dll")]

private static extern int DestroyWindow(IntPtr hWnd);


[DllImport("coredll.dll")]

private static extern int SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,

int X, int Y, int cx, int cy, int uFlags);


private void menuItem1_Click(object sender, EventArgs e)

{

// Find the spinner control associated with the textbox

IntPtr spin = GetWindow(textBox1.Handle, GW_HWNDNEXT);

// Destroy the spinner

DestroyWindow(spin);

// Move the textbox control to take up the entire

// client space

IntPtr container = GetParent(textBox1.Handle);

SetWindowPos(textBox1.Handle, container, 0, 0,

textBox1.Width - 1, textBox1.Height, 0);

}


private void TextBox1_KeyDown(object sender, KeyEventArgs e)

{

// disable the ENTER key

if (e.KeyCode == Keys.ENTER) e.Handled = true;

}


Reference:

http://social.msdn.microsoft.com/Forums/en-US/netfxcompact/thread/8272ec73-920f-4c04-ad38-1bca35598317/

Read More »

Add Cut/Copy/Paste functionality to WM Textboxes

Allow user to display a context menu with cut/copy/paste functionalities to textboxes by tap & hold, y using Windows CE's SIPPREF control to automatically implement default input panel behavior for a dialog. It provides the following features:

  • The Input Panel is automatically shown/hidden as controls gain and loose focus.
  • Edit controls have an automatic context menu with Cut, Copy, Paste type options.
  • The SIP state is remembered if the user switches to another application and later returns to this form

In order to use the SIPPREF control we must first request the operating system to register the SIPPREF window class. We do this by calling the SHInitExtraControls function. This step only needs to be done once, so is typically done during your application’s start up code. It is very easy to call, as the following example demonstrates:


#include
SHInitExtraControls
();


Once we have registered the SIPPREF window class, we simply create a SIPPREF control as a child of our dialog. When the SIPPREF control is created it will enumerate all sibling controls and subclass them in order to provide the default SIP handling behaviour. The SIPPREF control must be the last control added to your dialog, as any controls added after the SIPPREF control will not be present when the SIPPREF control enumerates its siblings, and hence will not be subclassed to provide the proper SIP handling.


If dynamically creating the SIPPREF control, a good place to do this is within the WM_CREATE or WM_INITDIALOG message handler, as the following code sample demonstrates:


case WM_INITDIALOG:
// Create a SIPPREF control to handle the SIP. This
// assumes 'hDlg' is the HWND of the dialog.
CreateWindow(WC_SIPPREF, L"", WS_CHILD,
0, 0, 0, 0, hDlg, NULL, NULL, NULL);


.NET CF Sample Code via P/invoke


Note: if a panel is used, hWndParent passed to CreateWindowEx should be the handle of the panel, otherwise there is no effect!


[DllImport("aygshell.dll")]
private static extern int SHInitExtraControls();

[DllImport("coredll.dll")]
private static extern IntPtr CreateWindowEx(
uint dwExStyle,
string lpClassName,
string lpWindowName,
uint dwStyle,
int x,
int y,
int nWidth,
int nHeight,
IntPtr hWndParent,
IntPtr hMenu,
IntPtr hInstance,
IntPtr lpParam);

private static readonly string WC_SIPPREF = "SIPPREF";
private static readonly uint WS_CHILD = 0x40000000;


protected override void OnLoad()
{
// Initialise the extra controls library
SHInitExtraControls();

// Create our SIPPREF control which will enumerate all existing
// controls created by the InitializeControl() call.
IntPtr hWnd = CreateWindowEx(0, WC_SIPPREF, "", WS_CHILD,
0, 0, 0, 0, this.Handle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}


Reference: http://www.christec.co.nz/blog/archives/146

Read More »