Predict the tech future with Engadget blog



Engadget Logo

Engadget blog gets you very interesting tech news at your desk. It’s about gadgets such as laptops, desktops, mobile phones, cars or any new electronic items. You can see the market trends and make appropriate decisions for your business. What mobile phone platform is popular, which is not worth concentrating on. This is why I subscribe to this blog.

Thanks.



theform.__eventtarget is null or not an object



If you get this error in your aspx page, you may end up spending several hours (like i did) before finding the actual cause. Actually, this error could cause due to multiple reasons. One of the reason is mentioned below:

ASP.Net generates a lot of javascript, form code etc based on the web form. When generating objects, it assigns an ‘id’ to it. If that ‘id’ clashes with one of our web form ids, you might see this error “theform.__eventtarget is null or not an object“.

A common scenario is when assigning an id to forms. ASP.Net automatically generates forms with ids form1, form2 etc. If your web form also contains the same id, then you might see this error.

Thanks.



SendInput Function



We had to use the “SendInput Function” to send keystrokes to any active window in our program PikyFolders.

We had troubles using it first. We also referred to many other samples on the Internet. But still it was not clear that after sending every keystroke we must also send the same keystroke with the KEYEVENTF_KEYUP flag to indicate that the key is released.

Basically, to type the character ‘A’, you would need to fill in 2 INPUT structures, one for pressing (without KEYEVENTF_KEYUP flag) and another for releasing (with KEYEVENTF_KEYUP flag).

So for example, if you want to simulate Shift+A, the array of INPUT structures would be as follows.

Press Shift
Press A
Release A
Release Shift

Hope this helps somebody out there.



The Association Of Shareware Professionals



The ASP (Association Of Shareware Professionals)

Yes. I would recommend that you join this association, especially if you are new to the software business world. The Association of Shareware Professionals (The ASP) is a forum of more than 1500 software professionals around the world. The most valuable thing is their private newsgroups where the software developers discuss about marketing, development, business tips, software protection, infrastructure recommendation, discount offers and much more.

Don’t go on their website. It may seem dull and outdated. But their private newsgroups are worth the $100.00 yearly membership fee.



Coder’s Toolbox – Simple, very useful tools for developers



Recently, I stumbled upon a simple website with some very useful tools that a programmer from any platform would need. It is called the Coder’s Toolbox.

Here are the tools that it supports:

  • Convert between Unix timestamp, ISO8601 and RFC 2822 formats
  • Encode/decode Base64-encoding; escape XML, URL’s and ECMAScript; translate to UTF-8
  • Convert between decimal, hexadecimal, octal and binary numbers
  • Calculate netmasks, broadcast addresses and do DNS lookups
  • Calculate the duration of file transfer
  • Test your XPath expressions


You must know about StackOverflow.com



StackOverflow

StackOverflow is a fantastic question/answer site for all developers. Beware! You might get addicted to it.

It is just around one month since its launch and it already has about 30,000 questions covering all kinds of platforms.

Ask a question, press refresh few times and you are very likely to see the answer to your question. Impressive isn’t it?

What I like the most is the voting system. The best answers are shown on top and the not-so-good answers move towards bottom.



Using SetForegroundWindow to activate another process’ window



Thanks to the Dr. Dobb’s Portal article which revealed the secret of bringing another process’ window using SetForegroundWindow API.

Sometimes, you may launch another process using CreateProcess or ShellExecute API. But the focus may remain in the current process instead of the new process that you just spawned. You might see the new process’ window button blinking in the taskbar wanting the user to activate it.

Here is the code that will let you to activate another process’ window.

 
HWND hWndCurrentWindow = GetForegroundWindow();
CString strTitleNewWindow;
strTitleNewWindow.LoadString(IDS_APPTITLE_NEWWINDOW);
HWND hNewWindow = FindWindow(NULL, strTitle);
if (hNewWindow)
{
	DWORD hCurrentWindowThread = GetWindowThreadProcessId( hWndCurrentWindow, NULL );
	DWORD hNewWindowThread = GetWindowThreadProcessId( hNewWindow, NULL);
	AttachThreadInput( hCurrentWindowThread, hNewWindowThread, TRUE );
	SetForegroundWindow(hNewWindow);
	AttachThreadInput( hCurrentWindowThread, hNewWindowThread, FALSE );
}


Building Visual C++ Programs for 64 bit Windows



Most of the 32 bit Windows programs would run successfully in 64 bit Windows (XP, Vista & above). But in some cases your 32 bit Windows program may fail on a 64 bit Windows operating system.

Here are some common cases, I have covered:

  • You have a 32 bit DLL that is a COM plug-in to some of the standard Windows programs such as Windows Explorer, Internet Explorer, Shell Extension etc.
  • You have a 32 bit system hook DLL which all the processes must load.

This article talks about building the DLL using Visual C++ 9.0 (Visual Studio 2008).

My development machine is Windows XP (32 bit). I assumed that in order to build 64 bit programs, one must compile the project on a 64 bit operating system. But this is not the case.

The good news is that you can build 64 bit programs on a Win32 OS also. However, you cannot debug the programs on Win32 OS. You will need Win64 OS to debug. My DLLs were pretty straight forward. So I built the DLLs on Win32 OS and tested them on Win64 OS.

Installing x64 Compilers

Visual Studio 2008 comes with x64 compilers. By default, they are deselected during installation. Install them from your CD if you haven’t done so.

Compiling 64 bit DLL/EXE

  1. Open your Visual C++ Solution
  2. Choose Build->Configuration Manager menu
  3. Inside the Configuration Manager window, change the ‘Active solution platform’ to x64. If you don’t have any, you would need to create one by selecting the ‘New..’ drop down item. Copy settings from your Win32 platform.
  4. Now rebuild your solution.

Typically, the output files are created under the folder \. Example: x64\Release or x64\Debug.

When compiling you might get some warnings/errors due to the change in platform. You may have to use INT_PTR instead of int. DWORD_PTR instead of DWORD. The return types for OnTimer function may need to be changed etc.

If you have any Win64 specific code, then use the _WIN64 macro to separate it from the Win32 code. At runtime, to check if the current operating system is 64 bit, call the function GetSystemWow64Directory. If it succeeds then it means that the operating system is 64 bit. Some developers suggest using the IsWow64Process function to detect the operating system type, but it is not recommended based on MSDN documentation.

Remember, you would need to link to 64 bit versions of any third party DLLs that you are using. The linker will automatically pick the 64 bit versions of the standard runtime DLLs such as MFC, ATL, CRT etc.

The VC++ Directories (Tools->Options->Projects and Solutions) are platform specific. So you will need to specify a different set of directories for your third party 64 bit DLLs.

Deploying both 32 bit and 64 bit COM DLLs

In some cases, such as shell extensions, you may need to deploy both 32 bit DLLs and 64 bit DLLs, so that 32 bit processes can load the 32 bit DLL, while 64 bit processes can load the 64 bit DLL.

You don’t need two different GUIDs. Both the DLLs can have the same GUIDs. The 32 bit DLL must be registered using 32 bit Regsvr32.exe. While the 64 bit DLL must be registered using 64 bit Regsvr32.exe. This will ensure that both the registration happen in their own separate areas of the registry.

You will find the Regsvr32.exe in following locations:

C:\Windows\System32\regsvr32.exe (64 bit)
C:\Windows\SysWow64\regsvr32.exe (32 bit)

To register successfully using regsvr32.exe, you will need to launch Command Prompt as an administrator. To do this, right click on ‘Command Prompt’ and choose ‘Run as Administrator’.

The registry in Win64 has different areas for storing 32 bit COM registrations.

To view the 64 bit Registry, run:
C:\Windows\System32\regedit.exe

To view the 32 bit Registry, run:
C:\Windows\SysWow64\regedit.exe -m
We are using -m so that a separate instance of Registry Editor can be run while the 64 bit Registry Editor is running

Deploying both 32 bit and 64 bit hook DLLs

In case of system wide hook DLLs, you will need to have 2 DLLs (32 bit and 64 bit) and 2 EXEs (32 bit and 64 bit) that will actually hook the DLLs. So, at anytime you will have 2 EXEs running. One for each DLL.



Deleting files left after installing vcredist_x86.exe using ‘Inno Setup’



VC Redistribulables from VC++ 2008 (9.0) installs temporary files in system root directory. This is a known bug as mentioned in this Microsoft’s KB Article 950683.

Actually, it installs temporary files in the drive with maximum free space (not the system root).

Until Microsoft fixes it in VC 2008 SP1, we will need to find our own workaround. Here is an ‘Inno Setup’ script that deletes the 24 temporary files from the drive with maximum free space.

We do not find which drive has maximum free space. Instead we just check each drive from C:\ to M:\ for a subset of files. If they exist, then we start deleting all the 24 files.

Update: The 64 bit version of the redistributable vcredist_x64.exe also has the same problem. Also, they seem to have fixed this problem in VC++ 2008 Redistributables SP1. I haven’t tested it yet because its size has bloated up from 1.7 MB to 4 MB.

Here is the code

 
procedure DeleteVCRedistRuntimeTemporaryFiles();
var
   i : Integer;
   byCounter : Byte;
   byDrive : Byte;
   strFile1, strFile2, strFile3 : String;
   strRootDrivePath : String;
   //totally there are 24 files to be deleted
   arrFiles : Array [1..24] Of String;
begin
 
 
   //We will check the following root drives
   //C, D, E, F, G, H, I, J, K, L, M
   For byCounter := 67 to 77 do
   Begin
      strRootDrivePath := Chr(byCounter) + ':\';
      arrFiles[1] := strRootDrivePath + 'vcredist.bmp';
      arrFiles[2] := strRootDrivePath + 'VC_RED.cab';
      arrFiles[3] := strRootDrivePath + 'VC_RED.MSI';
 
      //If these 3 files then we have found the right
      //drive in which the VC runtime files are extracted
      If (FileExists(arrFiles[1]) And
          FileExists(arrFiles[2]) And
          FileExists(arrFiles[3])) Then
      Begin
 
          arrFiles[4] := strRootDrivePath + 'eula.1028.txt';
          arrFiles[5] := strRootDrivePath + 'eula.1031.txt';
          arrFiles[6] := strRootDrivePath + 'eula.1033.txt';
          arrFiles[7] := strRootDrivePath + 'eula.1036.txt';
          arrFiles[8] := strRootDrivePath + 'eula.1040.txt';
          arrFiles[9] := strRootDrivePath + 'eula.1041.txt';
          arrFiles[10] := strRootDrivePath + 'eula.1042.txt';
          arrFiles[11] := strRootDrivePath + 'eula.2052.txt';
          arrFiles[12] := strRootDrivePath + 'eula.3082.txt';
          arrFiles[13] := strRootDrivePath + 'globdata.ini';
          arrFiles[14] := strRootDrivePath + 'install.exe';
          arrFiles[15] := strRootDrivePath + 'install.ini';
          arrFiles[16] := strRootDrivePath + 'install.res.1028.dll';
          arrFiles[17] := strRootDrivePath + 'install.res.1031.dll';
          arrFiles[18] := strRootDrivePath + 'install.res.1033.dll';
          arrFiles[19] := strRootDrivePath + 'install.res.1036.dll';
          arrFiles[20] := strRootDrivePath + 'install.res.1040.dll';
          arrFiles[21] := strRootDrivePath + 'install.res.1041.dll';
          arrFiles[22] := strRootDrivePath + 'install.res.1042.dll';
          arrFiles[23] := strRootDrivePath + 'install.res.2052.dll';
          arrFiles[24] := strRootDrivePath + 'install.res.3082.dll';
 
 
          For i := 1 to 24 Do
          Begin
            DeleteFile(arrFiles[i]);
          End;
 
          //Now that we have found and deleted all the files
          //we will break
          Break;
      End;
   End;
End;
 
procedure DeinitializeSetup();
begin
 
    DeleteVCRedistRuntimeTemporaryFiles();
 
end;