Thursday, December 07, 2006

C++: Visual C++ 2005 Express Edition x64

Visual C++ 2005 Express Edition is a free 32 bit IDE and compiler offered by microsoft. It has limitations (no resource editor, no MFC) but you can build command line apps with it ok, and if you set it up properly you can build apps for x64. This is helpful particularly if you have an x64 system, and don't want to pay for Visual Studio 2005 which has support for x64 compilation. To enable x64 install the free Microsoft Platform SDK. Then depending on what you're programming you may want the .NET Framework SDK 2.0 (x64).

download links


After installing these, you need to configure Visual C++ Express to compile with the Platform SDK libraries.
go to Tools > Options > Projects and Solutions > VC++ Directories and set the following:
Executable files: C:\Program Files\MS_Platform_SDK\Bin
Include files: C:\Program Files\MS_Platform_SDK\Include
Library files: C:\Program Files\MS_Platform_SDK\Lib
Note: depending on where you installed the platform sdk you may have to use "Microsoft Platform SDK for Windows Server 2003 R2" as "MS_Platform_SDK" above.


Now, open up the x64 open build debug/retail environment window (came with Platform SDK). It will look like a command-line interface. From that command-line go to the folder where "VCExpress.exe" is located and call it. Now when you build apps it will build with the x64 libraries.

Then, you need to modify some default settings in your projects.

To compile for x64, create 'x64' in the configuration manager for x64 (copy settings from win32), then verify and set the following project settings:
* /MACHINE (Specify Target Platform) is set to /MACHINE:AMD64.
* Register Output is turned OFF.
* If Debug Information Format was set to /ZI in the Win32 project configuration, then it is set to /Zi in the 64-bit project configuration. For more information, see /Z7, /Zi, /ZI (Debug Information Format).
* Values of WIN32 are replaced by WIN64 for /D (Preprocessor Definitions).


When linking, if you get errors like:
"error LNK2001: unresolved external symbol _RTC_Shutdown"
then set "Basic Runtime Checks" to Default in the project settings.

When linking, if you get errors like:
fatal error LNK1112: module machine type 'AMD64' conflicts with target machine type 'x64', you need to make sure you use /MACHINE:AMD64 and not /MACHINE:x64. If it won't let you, change to "Not Set", then add it explicitly under Additional Linker Options.

When running your app you may get an error saying msvcrtd.dll not found. Go to your platform SDK folder, and go to noredist/win64/amd64 and you will find it there, copy it into your system32 folder. Don't use the one in noredist/win64/ like i did at first, it doesn't help.

sources:
http://msdn2.microsoft.com/en-us/library/9yb4317s(VS.80).aspx
http://www.planetamd64.com/lofiversion/index.php/t18796.html
http://www.planetamd64.com/lofiversion/index.php/t5934.html

CSS: Block IE 'active content' bar

I don't know what implications this has, the IE 'warning active content' bar pops up on safe CSS using ActiveX, but the message may be coming up legitimately.

Problem: I wanted to have a fancy gradient in the background of a button for IE users only. I found css code supposedly uses activeX to achieve this.
CSS code:
.btn { filter:progid:DXImageTransform.Microsoft.Gradient(
GradientType=0,StartColorStr='#ffD3D7E0',EndColorStr='#ff8C939B');}


But when I view the HTML page on my local computer I see:
"To help protect you security, Internet Explorer has restricted this file from showing active content that could access your computer"

Solution: I found a forum that said when you deploy it to HTTP this message goes away. Another alternative is to include the following code.

<!-- Start Information Bar Blocking Code -->
<!-- saved from url=(0027)http://www.blockingspoof.com/dumbie.html -->
<!-- End Information Bar Blocking Code -->


However I noticed that while the IE-Bar goes away, I don't think it addresses this issue: (an IE security flaw which I also found) which leads me to think the IE Bar is legitimately popping up (because of insecure code).
see: http://osvdb.org/27109

Thursday, November 30, 2006

C++: Visual C++ 2005 Express Edition

Visual C++ 2005 Express Edition is a free IDE and compiler offered by microsoft. It has limitations (no resource editor, no MFC) but you can build command line apps with it ok. They strip out a lot of stuff but you can install the free Microsoft Platform SDK to enable more features for Visual C++ 2005 Express. Then depending on what you're programming you may want the .NET Framework SDK 2.0 (x86).

download links


After installing these, you need to make the Visual C++ Express able to see the Platform SDK libraries.
go to Tools > Options > Projects and Solutions > VC++ Directories and set the following:
Executable files: C:\Program Files\MS_Platform_SDK\Bin
Include files: C:\Program Files\MS_Platform_SDK\Include
Library files: C:\Program Files\MS_Platform_SDK\Lib
Note: depending on where you installed the platform sdk you may have to use "Microsoft Platform SDK for Windows Server 2003 R2" as "MS_Platform_SDK" above.

Then, you need to modify some default settings in your projects. Edit the corewin_express.vsprops file in
C:\Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults and add the following to AdditionalDependencies: " user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib"

You can enable a windowed template in the Visual Studio Express:
Edit the file AppSettings.htm in
C:\Program Files\Microsoft Visual Studio 8\
in subfolder \VC\VCWizards\AppWiz\Generic\Application\html\1033\ and comment out the following 4 lines (approx line 440)
// WIN_APP.disabled = true;
// WIN_APP_LABEL.disabled = true;
// DLL_APP.disabled = true;
// DLL_APP_LABEL.disabled = true;


Then when go to build an application choose a Win32 Console Application. In the Win32 Application Wizard dialog box, make sure that Windows application is selected as the Application type and the ATL is not selected. (before you edited the AppSettings.htm file, this was disabled. Click the Finish button to generate the project.

This post is pretty much a regurgitation of the following link. So for more information go check it out. I originally had this post for x64 and x86 but decided to split. This one was the x86 so go check out my other x64 post.

source: http://msdn.microsoft.com/vstudio/express/visualc/usingpsdk/

Tuesday, November 28, 2006

C++: Read-only member function

class MyClass
{
private:
int _AsInteger;
public:
const int &AsInteger;

MyClass() : _AsInteger(0), AsInteger(_AsInteger)
{
}

void SetDefault()
{
_AsInteger= 17;
}
};


MyClass obj1;
int a = obj1.AsInteger; //success
obj1.AsInteger= 1337; //compiler error
This way, you have a member that appears public but really isn't.

Monday, November 20, 2006

XML: Embed tags (other XML or HTML) in XML

Use CData to embed html or other xml in your xml
<doc_root>
<
data>
<![CDATA[
<b>text</b>
]]>
</data>
</
doc_root>

Friday, October 27, 2006

WIN32: Build a basic Windows installer with NSIS

Its not that hard to write a program that copies a bunch of files to another folder, but sometimes it is nice to have a program that takes care of the license agreement, registry keys, start menu creation, copying to a program files folder and uninstaller all in one self-extracting archive.

There are many installers available, I decided to go with the Nullsoft Scriptable Install System (NSIS) as it is open source. I used the following settings in my script, I should have provided enough that you should do find-replaces on the provided script to customize for your basic needs. For anything else go look at the NSIS documentation, its pretty good.

Settings-
Language: English
Program Name: Popcorn Maker
Program .EXE: popcorn.exe
Program .DLLs: popcorn1.dll, popcorn2.dll
EULA File (for installer): TermsOfUse.txt
Installer .EXE: pm_installer.exe
Splash bitmap: res/splash3.bmp (res is relative to your NSIS script)
Installer Icon: res/installer.ico
Uninstaller Icon: res/uninstaller.ico

[1] Go to http://nsis.sourceforge.net, download and install the Nullsoft Scriptable install system.

[2] Look at their example scripts and get a feel for how you want to design your installer. They provide 20+ example scripts from basic, to complex, even including the source for the installer that they used to install the NSIS that you downloaded.

[3] Use the following script. Save it as a .NSI filetype and put it in the same folder as your .EXE file and res folder (setup as shown above).

;--------------------------------
;Include Modern UI

  !
include "MUI.nsh"

;--------------------------------
;Splash screen
XPStyle on

Function .onInit
  ; the plugins dir is automatically deleted when the installer exits
  
InitPluginsDir
  File /oname=$PLUGINSDIR\splash3.bmp ".\res\splash3.bmp"

  
advsplash::show 1500 600 0 -1 $PLUGINSDIR\splash3
  ;splash3.bmp is a splash screen that fades in for
  ;1500 ms holds for 600 ms and fades out for 0 ms

  
Pop $0
  
; $0 has '1' if the user closed the splash screen early,
  ; '0' if everything closed normally, and '-1' if some error occurred.
FunctionEnd

;--------------------------------
;General

  ;Name and file
  
Name "Popcorn Maker"
  
OutFile "pm_installer.exe"

  
;Default installation folder
  
InstallDir "$PROGRAMFILES\Popcorn Maker"

  
!define MUI_ICON ".\res\installer.ico"
  
!define MUI_UNICON ".\res\uninstaller.ico"

  
!define MUI_FINISHPAGE_NOAUTOCLOSE
  !define MUI_UNFINISHPAGE_NOAUTOCLOSE
;--------------------------------
;Variables
  
Var STARTMENU_FOLDER
  Var MUI_TEMP
;--------------------------------
;Interface Settings
  !
define MUI_ABORTWARNING
  !define MUI_STARTMENUPAGE_DEFAULTFOLDER "Popcorn Maker"
;--------------------------------
;Pages
  !
insertmacro MUI_PAGE_LICENSE ".\TermsOfUse.txt"
  
!insertmacro MUI_PAGE_COMPONENTS
  !insertmacro MUI_PAGE_DIRECTORY

  ;Start Menu Folder Page Configuration
  !
define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKCU"
  
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Popcorn Maker"
  
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
  
!define MUI_UN_REG "Software\Microsoft\Windows\CurrentVersion\Uninstall"

  
!define MUI_FINISHPAGE_RUN "$INSTDIR\popcorn.exe"
  
!define MUI_FINISHPAGE_NOREBOOTSUPPORT

  !insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER

  !insertmacro MUI_PAGE_INSTFILES

  !insertmacro MUI_PAGE_FINISH

  !insertmacro MUI_UNPAGE_CONFIRM
  !insertmacro MUI_UNPAGE_INSTFILES

;--------------------------------
;Languages

  !
insertmacro MUI_LANGUAGE "English"

;--------------------------------
;Installer Sections

Section "Popcorn Maker (Core)" SecMain
  SectionIn RO

  SetOutPath "$INSTDIR"

  
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application

  File .\popcorn.exe
  File .\popcorn1.dll
  File .\popcorn2.dll

  ; Write the installation path into the registry
  
WriteRegStr HKCU "Software\Popcorn" "Install_Dir" "$INSTDIR"

  
; Write the uninstall keys for Windows
  
WriteRegStr HKCU "MUI_UN_REG\Popcorn" "DisplayName" "Popcorn Uninstaller"
  
WriteRegStr HKCU "MUI_UN_REG\Popcorn" "UninstallString" '"$INSTDIR\un.exe"'
  
WriteRegDWORD HKCU "MUI_UN_REG\Popcorn" "NoModify" 1
  
WriteRegDWORD HKCU "MUI_UN_REG\Popcorn" "NoRepair" 1
  
WriteUninstaller "un.exe"

  
;Create shortcuts
  
CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
  
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Popcorn Maker.lnk" "$INSTDIR\Popcorn.exe"
  
CreateShortCut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Un.exe"

  
!insertmacro MUI_STARTMENU_WRITE_END

SectionEnd

;--------------------------------
;Descriptions

  ;Language strings
  
LangString DESC_SecMain ${LANG_ENGLISH} "Popcorn Maker, a program"

  
;Assign language strings to sections
  !
insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
    !insertmacro MUI_DESCRIPTION_TEXT ${SecMain} $(DESC_SecMain)
  !
insertmacro MUI_FUNCTION_DESCRIPTION_END

;--------------------------------
;Uninstaller Section
Section "Uninstall"

  
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP

  Delete "$SMPROGRAMS\$MUI_TEMP\Popcorn Maker.lnk"
  
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"

  
;Delete empty start menu parent diretories
  
StrCpy $MUI_TEMP "$SMPROGRAMS\$MUI_TEMP"

  
smDeleteLoop:
    
ClearErrors
    RMDir $MUI_TEMP
    GetFullPathName $MUI_TEMP "$MUI_TEMP\.."

    
IfErrors smDeleteLoopDone

    StrCmp $MUI_TEMP $SMPROGRAMS smDeleteLoopDone smDeleteLoop
  smDeleteLoopDone:

  
Delete "$INSTDIR\popcorn.exe"
  
Delete "$INSTDIR\popcorn1.dll"
  
Delete "$INSTDIR\popcorn1.dll"
  
Delete "$INSTDIR\Un.exe"
  
RMDir "$INSTDIR"

  
DeleteRegValue HKCU "MUI_UN_REG\Popcorn" "DisplayName"
  
DeleteRegValue HKCU "MUI_UN_REG\Popcorn" "UninstallString"
  
DeleteRegValue HKCU "MUI_UN_REG\Popcorn" "NoModify"
  
DeleteRegValue HKCU "MUI_UN_REG\Popcorn" "NoRepair"
  
DeleteRegKey   HKCU "MUI_UN_REG\Popcorn"
  
DeleteRegValue HKCU "Software\Popcorn" "Install_Dir"
  
DeleteRegKey   HKCU "Software\Popcorn"

SectionEnd




Note: I'm always fighting with the width of blogspot, so i changed the font to Arial to fit more in. Sometimes the commands wrapped to the next line, but you can kind of tell. When you actually run it you'll have to put the wrapped text back on the original line.

Monday, September 18, 2006

FTP: Automated sessions via script

So you know how to use command line ftp clients, but you're not sure how to automate them with scripts.

WINDOWS (command-line)

ftp -s:script1.txt 11.11.11.11

script1.txt
username
password
ftp command1
ftp command2
quit

where username is the ftp username, password is their password. ftp command1 is any command line ftp commands like "get filename.zip" (download) or "put filename.rar" (upload).

Now its less important what the contents of the script are, and more important how to execute the script because once you know how, you can go use the commandline ftp client to run through whatever you want to automate, and make sure you have one command per line.

The only differences with the next command are that the hostname is embedded inside the script, and I replaced hostnames, usernames and passwords (etc) with more real examples.

ftp -s:script2.txt

script2.txt
open 192.168.0.123
gus
secretp123
put magicfile.zip
quit


LINUX

At the linux shell (command-line) type this command.
ftp < script2.txt

Because linux just uses i/o redirection, with the < symbol, one should use the format of script2 where the first line of the file is 'open [hostname]'.

USEFUL FTP COMMANDS
SERVER COMMANDS
# cd change directory on the remote SERVER
# cd .. change directory up one level on the remote SERVER
# pwd print the current directory you are within on the remote SERVER
# ls list files within the current directory on the remote SERVER
# binary prepare FTP to transfer binary files such as apps or images
# ascii prepare FTP to transfer ascii or text files such as .html files
# put copy a specific file from the local machine to the remote SERVER
# get copy a specific file from the remote SERVER to the local PC
# chmod change file permissions on a remote SERVER if you have access
# del delete a specific file on the remote SERVER
# bye end your FTP connection

LOCAL MACHINE
# lcd change directory on your local PC
# lcd .. change directory up one level on your local PC
# lpwd print the current directory you are within on your local PC


sources: http://support.microsoft.com/?kbid=96269 and http://www.reallylinux.com/docs/autoftp.shtml

Tuesday, September 12, 2006

DOS: Using winzip for command line

You want to automate compression and you remember pkunzip.exe and pkzip.exe of yesteryear. It turns out winzip can be used from the command line and embedded into a batch (.BAT) file for automation. (oooh automated backups).

The command format is:

 winzip32 [-min] action [options] filename[.zip] file(s)


-min this specifies that WinZip should run minimized. If -min is specified, it must be the first command line parameter.

action
-a for add, -f for freshen, -u for update, and -m for move. You must specify one (and only one) of these actions. The actions correspond to the actions described in the section titled "Add dialog box options" in the online manual.

options
-r corresponds to the Include subfolders checkbox in the Add dialog and causes WinZip to add files from subfolders. Folder information is stored for files added from subfolders. If you add -p, WinZip will store folder information for all files added, not just for files from subfolders; the folder information will begin with the folder specified on the command line.

-ex, -en, -ef, -es, and -e0 determine the compression method: eXtra, Normal, Fast, Super fast, and no compression. The default is "Normal". -hs includes hidden and system files. Use -sPassword to specify a case-sensitive password. The password can be enclosed in quotes, for example, -s"Secret Password".

filename.zip
Specifies the name of the Zip file involved. Be sure to use the full filename (including the folder).

files
Is a list of one or more files, or the @ character followed by the filename containing a list of files to add, one filename per line. Wildcards (e.g. *.bak) are allowed.

examples:

 winzip32.exe -min -a -r c:\myfiles\ c:\output.zip


this creates an output.zip with all the files in the c:\myfiles\ folder. if winzip isn't in your path, you may have to use "c:\program files\winzip32.exe" instead of winzip32.exe above,

 winzip32 -a "c:\My Documents\file1.doc" c:\output2.zip


this creates an output2.zip but note how the path must be enclosed in quotation marks because there is a space in it. Also winzip32.exe and winzip32 in the 2 examples are equivalent.

source: http://www.memecode.com/docs/winzip.html

Saturday, September 09, 2006

JBOSS: Deploying a win32 project on linux

When you copy a jboss project from a windows (eclipse) programming environment there are two important things to remember.

Modify permissions
1. chmod 775 $JBOSS_HOME/server/default/deploy/ProjectName.war

Fix WEB-INF
2. Change web-inf folder to uppercase WEB-INF

JBOSS: Running JBoss as a Service

Starting JBoss as a service:
http://wiki.jboss.org/wiki/Wiki.jsp?page=StartJBossOnBootWithLinux

More Linux tutorials (relative to startups)
http://yolinux.com/TUTORIALS/LinuxTutorialInitProcess.html

LINUX: Useful commands

ps -aux|grep java //show processes containing 'java'
top //display processes list
passwd //change current users password
passwd gus123 //change password user gus123
service iptables stop //stops firewall from running
chkconfig iptables off//firewall won't start on boot

tail -f textfile//turns a log file thats being
//generated into a console
netstat -a //shows port usage
touch <file> //update timestamp of file
dd if=/dev/zero of=/dev/hda/ bs=512 count=1//wipe mbr
free -m //check mem usage
du -x --block-size=1024K | sort -nr | head -10
//10 biggest folders in current path
wc -l gives linecount


Memory Usage Tools useful
http://www.ss64.com/bash/ also useful

J2EE: Linux J2EE Server Setup

I ran the j2ee for linux installer and had issues:

[root@cs462-2-1 src]#./java_ee_sdk-5-linux.bin
Checking available disk space...
Checking Java(TM) 2 Runtime Environment...
Launching Java(TM) 2 Runtime Environment...
Deleting temporary files...


But then it would appear to hang. Well it wasn't really hanging. I've installed j2ee sdk before in linux on suse where there was a gui available, but this time I needed to do it via linux terminal (command line).

Solution: use the -console flag
[root@cs462-2-1 src]#./java_ee_sdk-5-linux.bin -console


Once we used the -console flag we were able to get past the "Deleting temporary files" output, and were give a console based installer UI that made us say yes to a license agreement, and choose the install path etc.

Friday, June 30, 2006

PHP: Variable length parameters

When you want to write a function that can use any number of parameters/arguments there are 2 ways.

The first uses defaults and appears as if you are using a variable number of arguments. You have to know the maximum number of parameters/arguments, and for each one you must specify a default. This is shown below in the function href1().

The second is the actual way to get a variable number of parameters/arguments from the function. You use func_num_args() which is the number of arguments, and func_get_arg($i) to fetch each argument (where $i is the argument number).

function ahref1($a="these",$b="are",$c="fake",$d="links")
{
$str="";
$str.="<a href='javascript:void(0);'>$a</a><br>\n";
$str.="<a href='javascript:void(0);'>$b</a><br>\n";
$str.="<a href='javascript:void(0);'>$c</a><br>\n";
$str.="<a href='javascript:void(0);'>$d</a><br>\n";
return $str;
}
function ahref2()
{
$str="";
for($i = 0 ; $i < func_num_args(); $i++)
{
$str.="<a href='javascript:void(0);'>";
$str.=func_get_arg($i)."</a><br>\n";
}
return $str;
}


echo ahref1();
echo ahref1('these');
echo ahref1('these','are');
echo ahref1('these','are','fake');
echo ahref1('these','are','fake','links');
echo ahref2('these','are','fake','links');


In each of the function calls above to href1() and href2(), they all produce the same results:

<a href='javascript:void(0);'>these</a><br> 
<a href='javascript:void(0);'>are</a><br>
<a href='javascript:void(0);'>fake</a><br>
<a href='javascript:void(0);'>links</a><br>

Thursday, May 11, 2006

AJAX: Back Button Fix with PHP and HTML Frames

UPDATED: 2008-10-02 Working Demo, and refined solution to the AJAX Back Button Fix is now available at zedwood.com.


So your back button is broken in your AJAX/PHP web app. I made a fix using PHP and HTML frames.

Flash developers have had to deal with this issue for a while, and so my fix is a variant. View Robert Penner's flash fix.

Lets say you are at a regular website with 5 pages total. After a user navigates from page1 to page2 he may want to click BACK to change the state of the website from page2 back to page1. Well in AJAX your website is no longer divided up into pages, but you must still use the idea of states that intuitively appears to the user as a different page.

So each AJAX page state is arrived at by executing a javascript function. When you click back, you'll want to execute a previous AJAX function which returns the site to the previous page state. This is accomplished with frames, but this means that if a browser is not enabled to use frames (lynx), the back button will not work. This is okay because no one would use lynx for your website anyway.

No what we have a frame overlay page, with two frames, one sized at 100%,100% and the other as invisible. When we hit a link that we want to store in the page history, we make change the page of the invisible frame to a new page, and pass it a parameter of the real page we wanted to go to. Then in our invisible frame we use that parameter to determine which ajax state to go to in the main page, which we arrive at by executing a javascript function. The effect is that when you hit the back button, it jumps to a previous page in the invisible frame and executes the javascript function associated with it, which changes the page state of the main ajax page.

Allowed Links. There are 3 kinds of links available to use on your site:
1. A HREF with _target='parent', used for external links to jump out of the framed ajax page
2. A HREF with onclick="pagenav('ajaxpagestate')" use this to navigate to a new ajax page state
3. Regular A HREF, do not use, because it will boot up the link within your frame overlay

Files needed for my PROOF-OF-CONCEPT(included below):
index.html- contains 2 frames index.php and redir_ph.php(invisible)
redir_ph.php- invisible frame used for storing page history
index.php- your main ajax app page
ajax.js- contains javascript code for ajax
ajaxfunc.php- ajax access this to returns famous quotes in xml


index.html
<html><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
head>
<
title></title>

<
meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<
/head>

<
frameset rows="*,0" frameborder="NO" border="0" framespacing="0">
<
frame src="index.php?useframes=true" name="realframe" frameborder="NO">
<
frame src="redir_ph.php?p=main" name="historyframe" frameborder="NO">
<
/frameset>

<
noframes>
<
body bgcolor="#FFFFFF">
<
script language="JavaScript">
<!---------
window.location.href='index.php';//index.php defaults to useframes=false
//-------->
<
/script>
<
/body>
<
/noframes>

<
/html>


ajax.js
//--ajax
function createRequestObject() {
if(navigator.appName == "Microsoft Internet Explorer")
return new ActiveXObject("Microsoft.XMLHTTP");
return new XMLHttpRequest();
}

var httpreq = createRequestObject();
function ajaxreq(quote) {
httpreq.open('get', 'ajaxfunc.php?t='+quote);
httpreq.onreadystatechange = ajaxresponse;
httpreq.send(null);
}
function ajaxresponse()
{
if(httpreq.readyState == 4)
{
var xml=httpreq.responseXML;
var node=xml.getElementsByTagName("quote")[0];
var quot=node.firstChild.nodeValue;
document.getElementById('maindiv').innerHTML=quot;
}
}


redir_ph.php
<?php
if ( isset($_REQUEST['p']) )
$pagename= rtrim($_REQUEST['p']);
else
$pagename="";

$jscript="if (parent.realframe.pagenavdone) parent.realframe.pagenavdone('$pagename');";
?>
<
html><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
head>
<
title><?php echo $pagename;?></title>
<
meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</
head>
<
body bgcolor="#000000" text="#FFFFFF">
<?
php echo $pagename;?>
<
script language="JavaScript">
<!---------
<?
php echo $jscript;?>
//-------->
</
script>
</
body>
</
html>


ajaxfunc.php
<?php
if ( isset($_REQUEST['t']) )
$t= rtrim($_REQUEST['t']);
else
$t="";

header('Content-type: text/xml');
echo "<quote>";
if ($t=="money")
echo "I spent 90% of my money on women and drink. The rest I wasted - George Best";
else if ($t=="fire")
echo "Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life. - Terry Pratchett.";
else if ($t=="love")
echo "Love is temporary insanity curable by marriage. - Ambrose Bierce";
else if ($t=="success")
echo "If at first you don't succeed... So much for skydiving. - Henry Youngman.";
else if ($t=="hate")
echo "I am free of all prejudices. I hate everyone equally. - WC Fields";
else
echo
"The first ninety minutes of a football match are the most important. - Bobby Robson";
echo "</quote>";
?>


index.php
<?php
if ( isset($_REQUEST['useframes']) )
$useframes= rtrim($_REQUEST['useframes']);
else
$useframes="false";
?>
<
html><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<
head>
<
meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<
title>My Main AJAX Page</title>
<
script language="JavaScript" type="text/JavaScript" src="ajax.js"></script>
<
script language="JavaScript" type="text/JavaScript">
<!---------
//--back button
var useframes=<?php echo $useframes;?>;
function pagenav(str)
{
if (useframes)
top.frames["historyframe"].location.href = "redir_ph.php?p="+str;
else
pagenavdone(str);
}
function pagenavdone(pagename)
{
if (pagename=="money_quote_state")
ajaxreq("money");
else if (pagename=="fire_quote_state")
ajaxreq("fire");
else if (pagename=="love_quote_state")
ajaxreq("love");
else if (pagename=="success_quote_state")
ajaxreq("success");
else if (pagename=="hate_quote_state")
ajaxreq("hate");
}
//-------->
</
script>
</
head>
<
body style='font-family:Arial,Geneva,Sans-Serif;font-size:10pt'>

This is my main ajax page 3.
<br>
<
br><a href='http://www.google.com' target='_parent'>
Use this type of A HREF for links external to you AJAX app
</a>
<
br>
<
br>Ajax Page States:
<
br>
<
a href='javascript:void(0);' onclick="pagenav('money_quote_state');">money</a>
| <
a href='javascript:void(0);' onclick="pagenav('fire_quote_state');">fire</a>
| <
a href='javascript:void(0);' onclick="pagenav('love_quote_state');">love</a>
| <
a href='javascript:void(0);' onclick="pagenav('success_quote_state');">success</a>
| <
a href='javascript:void(0);' onclick="pagenav('hate_quote_state');">hate</a>

<
div id='maindiv' style='height:50px;border:1px #000000 solid'></div>

<
br><a href='http://www.google.com'>Do not use a regular A HREF link like this</a>
<
br>If you do , you it display your http://www.mysite.com/index.html in the location bar
but show the content of the site you were trying to reach.
</
body>
</
html>

INSTALL: PHP5+APACHE2+WIN32

Installing php 5, apache 2 in a win32 environment is easy. Sometimes enabling extensions can be difficult, but we will be enabling php_curl.dll, php_mysql.dll, php_mcrypt.dll, and php_mssql.dll.

Download PHP5 zip package
(the .zip with all the extensions, not the .exe installer)
Download Apache2 from http://http.apache.org
(link to 2.2.2 /w no SSL)
Unzip PHP5 to C:\PHP
Run the apache2 installer

if you have a folder named C:\PHP\extensions rename it to C:\PHP\ext
rename C:\PHP\php.ini-recommmended to C:\PHP\php.ini
edit C:\PHP\php.ini,
change the extension_dir to "C:\php\ext" (include quotation marks)
remove the ; from line: ;extension=php_curl.dll
remove the ; from line: ;extension=php_mysql.dll
remove the ; from line: ;extension=php_mcrypt.dll
remove the ; from line: ;extension=php_mssql.dll

edit http.conf, add the following lines to the bottom (default location-
c:\program files\apache group\apache2\conf\http.conf)
LoadModule php5_module "c:/php/php5apache2.dll"
AddType application/x-http-php .php
# configure the path to php.ini
PHPIniDir "C:\php"

Now, right-click on "My Computer", go to "Properties", go to the "Advanced" tab, click on the "Environment Variables" button. Under "System" add ";C:\php;C:\php\ext" to your PATH variable.

create a file called
c:\program files\apache group\apache2\htdocs\phpinfo.php
containing the text
<?php phpinfo(); ?>


When you reboot next, your PATH settings will be available to all programs, your apache2 will load as a service, it will see the new version of the http.conf file with the modifications you made, and will see the new php.ini file with the modifications you made, and when you hit "http://localhost/phpinfo.php" you will see an html version of your php.ini file with all of the settings, and you will see sections for each of the php extensions you have enabled.

C++: How to get the Temp Directory

For the currently logged-in user, you can edit the TEMP and TMP folders. In Windows XP, if your right-click on My Computer, go to Properties, go to the Advanced tab, click on Environment Variables, and you can set TEMP and TMP from here.

But what if you are writing a program that needs to create a temporary file? windows.h provides us with the GetTempPath() function used below. The following program was taken from an MSDN coding example.

code to fetch it: [revised]
#include <windows.h>
#include <stdio.h>
#define BUFSIZE 4096

int main(int argc, char* argv[])
{
DWORD dwRetVal;
DWORD dwBufSize=BUFSIZE; // length of the buffer
char lpPathBuffer[BUFSIZE]; // buffer for path

// Get the temp path.
dwRetVal = GetTempPath(dwBufSize, lpPathBuffer);

if (dwRetVal > dwBufSize)
{
printf ("GetTempPath failed with error %d.\n",
GetLastError());
return (2);
}
printf("GetTempPath returned: %s", lpPathBuffer);
return (0);
}
Originally I had included code for Borland C++ Builder code which went and did a manual fetch from the registry, but a reader posted about GetTempPath. I'm more familiar with borland C++ than I am with ms visual studio and windows API commands, so thanks to kicheck for that.

kichik said...
GetTempPath works "on Windows 9x as well and requires a lot less code. It'll also fallback from TMP to TEMP to USERPROFILE to WINDIR in case any of those don't exist."

Thursday, May 04, 2006

PHP: No input file specified error

Sometimes people get this error when installing php as a CGI Binary, when setting up PHP5 IIS6.0 on Windows Server 2003.

Solution:
Edit php.ini, comment out doc_root, there is a problem with virtual servers.

Helpful Links:
http://www.visualwin.com/PHP/
http://www.peterguy.com/php/install_IIS6.html
http://wordpress.org/support/topic/4243

Thursday, April 13, 2006

MFC: Class Wizard Error "Object Required"

I did a couple google searches and found a few people stuck on this one.

In Visual Studio 2003 C++ you start the Class Wizard by doing [Add Class].

PROBLEM:
From a blank project, often the error 'Object Required' comes up. And nothing happens.

SOLUTION:
I did some google searches and found no answers, only people like me with the same question. I eventually found an answer. It gives an error because it requires stdafx.h. Add stdafx.h as a blank file and it should work okay.

This was discovered trying to do the MFC Tutorial Part 5, step 7:

http://www.codersource.net/mfc_tutorial_Part5.html

Tuesday, March 14, 2006

JAVASCRIPT: Redirect

I keep having to look this one up, so I posted it here so I could always find it.

<button 
onclick="window.location='http://www.mysite.com/';">


this also works:
<button 
onclick= "window.location.href='http://www.mysite.com/';">

Monday, March 13, 2006

HTML: No dotted line on links

In order to get rid of this dotted lines on links, you write code so link says 'when you click on my and therefore focus the cursor on me, then blur me'

<a href=http://www.google.com 
onFocus="if(this.blur)this.blur()">Google</a>

Saturday, March 04, 2006

C++: Edit The Registry in Borland C++ Builder 5


#include <registry.hpp>//put this line in your header file

void MakeSerKey(String gSerial)
{
TRegistry *Reg = new TRegistry();

Reg->RootKey = HKEY_LOCAL_MACHINE;
if(!Reg->KeyExists("SOFTWARE\\TestSoftware"))
{
if(!Reg->CreateKey("Software\\TestSoftware"))
{
ShowMessage("Can't Create Key","Error",MB_OK);
delete Reg;
return;
}

try
{
if(Reg->OpenKey("Software\\TestSoftware",FALSE))
{
Reg->WriteString("SERIAL",gSerial);
Reg->CloseKey();
}
else
{
ShowMessage("Registry RootDir error");
}
Reg->CloseKey();
}
catch(ERegistryException &E)
{
ShowMessage(E.Message);
delete Reg;
return;
}
}
delete Reg;
}

void UpdateSerKey(String gSerial)
{
TRegistry *Reg = new TRegistry();

Reg->RootKey = HKEY_LOCAL_MACHINE;
if(Reg->KeyExists("SOFTWARE\\TestSoftware"))
{
try
{
if(Reg->OpenKey("Software\\TestSoftware",FALSE))
{
Reg->WriteString("SERIAL",gSerial);
Reg->CloseKey();
}
else
{
ShowMessage("Can't open key.");
}
Reg->CloseKey();
}
catch(ERegistryException &E)
{
ShowMessage(E.Message);
delete Reg;
return;
}
}
delete Reg;
}

Wednesday, February 08, 2006

HTML: Remove Margins from web pages

Sometimes making a webpage can be frusterating. You make a table with width and height of 100% for positioning and it still doesn't fill up the whole webpage why? Margins.

Don't forget to set margins in your body tag.

<html>
<
head>
<
title>webpage title</title>
<
/head>

<
body bgcolor="#ffffff" leftmargin="0" marginwidth="0" topmargin="0" marginheight="0">
<
/body>
<
/html>


with CSS:
<style type="text/css">
body
{
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
</style>

Tuesday, January 31, 2006

LINUX: SUSE + APACHE2 + PHP + MYSQL + ODBC

SUSE + APACHE2 + MYSQL + PHP + ODBC = SAMPO

SAMPO is a type of LAMP install. The acronmym LAMP comes from Linux + Apache + Mysql + PHP.

I wrote this a while ago while consulting for a company with SAMPO needs. The goal was to host a php website on a linux webserver while the data was hosted on a windows mysql server. Only step 7 is specific to that where you end up pointing to the windows server across the network. Optional points in step 4 are specific to the client I was doing this for.
----------------------------
Meant to be included are a number of files:
testfile.html [inline at end]
phptest.php [inline at end]
mysqltest.php [inline at end]
myodbctest.php [inline at end]
odbc.ini [inline at end]
odbcinst.ini [inline at end]
MyODBC-3.51.11-2.i586.rpm [click to download]

Note:
A. Your linux machine's assumed IP Address is 192.168.0.2
B. commands to be typed at the command prompt start with 'command:' (some may need to be done as root)

1. Install Suse Linux 9.3
-In the screen labelled 'Installation Settings', click on 'Software'
-Make sure you select Standard System w/ KDE
-In the top-left of the screen, under Filter, select 'Search'
-Search and make sure all of the following packages have been selected
-apache2
-apache2-mod_php4
-apache2-prefork
-php4
-php4-bz2
-php4-curl
-php4-ftp
-php4-gd
-php4-mcrypt
-php4-mysql
-php4-session
-php4-unixODBC
-php4-zlib
-mysql
-mysql-client
-mysql-shared
-unixODBC
-openssl
-bison
-libxml2
-readline
-flex


2. Enable apache2 and mysql services
-After booting your system, go to
-Linux 'Start' Menu > System > Yast > Network Services > HTTP Server
-configure the http server
-Linux 'Start' Menu > System > Yast > System > System Services
-enable mysql and apache2 (now they will start when the machine reboots)

3. Test apache2
-Copy testfile.html to /srv/www/htdocs
-test it by viewing http://192.168.0.2/testfile.html

4. Test php
-edit php.ini
-set register_globals to On [optional]
-set display_errors to Off [optional]
-restart web server to apply php changes
-command: rcapache2 restart
-Copy phptest.php to /srv/www/htdocs
-test it by viewing http://192.168.0.2/phptest.php
-ensure phptest.php display information about mcrypt, odbc, and mysql

5. Setup mysql locally (not required but good to test mysql connectivity locally before testing it over the network)
-set mysql root password (below, change 'mysqlrootpassword' to your root password preserving quotes)
-command: /usr/bin/mysqladmin -u root password 'mysqlrootpassword'
-go into mysql and execute the following commands
-command: mysql -u root -p
create database testdb;
use testdb;
create table testtable (item_id char(10), item_desc char(100));
insert into testtable values ('001','This is test data 1');
insert into testtable values ('002','This is test data 2');
select * from testtable;
exit;

-Copy mysqltest.php to /srv/www/htdocs
-modify mysqltest.php to contain a reference to the mysql user and password that you setup (can be root)
-test it by viewing http://192.168.0.2/mysqltest.php

6. Setup unixODBC (best to test with database created in step 5)
-install MyODBC-3.51.11-2.i586.rpm
-as root, command: rpm -iv MyODBC-3.51.11-2.i586.rpm
-Copy odbc.ini and odbcinst.ini to /etc/unixODBC
-modify odbc.ini to contain a reference to the mysql user and password that you setup (can be root)
-test with isql (obviously modify mysqluser and mysqluserpassword to point to the user you setup)
-command: isql testdb mysqluser mysqluserpassword
-Copy myodbctest.php to /srv/www/htdocs
-modify myodbctest.php to contain a reference to the mysql user and password that you setup (can be root)
-test it by viewing http://192.168.0.2/myodbctest.php
-if it doesn't work go to the fix on 6a.

6a. unixODBC fix
-as root (su) execute the following commands at the shell:
-command: cd /usr/lib/php/extensions
-command: sed -i -e 's/libc.so.6/xxodbc.so/' unixODBC.so
-command: cd /usr/lib
-command: ln -s libodbc.so xxodbc.so
-command: rcapache2 restart
6a source: http://susewiki.org/index.php?title=PHP4_ODBC

7. Point to final distination
Now that you have a server with Suse + Apache + PHP + Mysql + unixODBC + MyODBC setup,
-setup odbc.ini and odbcinst.ini to point to a windows mysql server over the LAN
-you may have to open a hole in the windows mysql server firewall at port 3306 to allow mysql connections through

======================================
ATTACHED FILES
======================================
testfile.html
If you can see this in <b>bold</b> your
http server is working.


phptest.php
<? echo phpinfo(); ?>



mysqltest.php
<?php
echo "just checking";
$link = mysql_connect('localhost', 'root', 'r00tpwd') or
die('not connect');

echo "\ngood connect";

mysql_select_db('testdb') or ('not select db');

$query = 'SELECT * from testtable';
$result = mysql_query($query) or die('Query failed');

while($line = mysql_fetch_array($result, MYSQL_ASSOC))
{
print_r($line);
}

mysql_free_result($result);

mysql_close($link);
?>



myodbctest.php
<?php echo "just checking";
$conn = odbc_connect('mysqltest', 'root', 'r00tpwd')
or die('error connecting');

echo 'connected successfully';

$sql = "select * from testtable";
$rs = odbc_exec($conn, $sql);
while(odbc_fetch_row($rs))
{
$f1 = odbc_result($rs, 1);
$f2 = odbc_result($rs, 2);

echo "
QUERY RESULTS:" .$f1." ".$f2;
}

?>


odbc.ini
[mysqltest]
Description = MySQL ODBC Database
Driver = MyODBC
Server = localhost
Database = testdb
#Port =
#Socket =
#Opinion =
#Stmt =


odbcinst.ini
[MyODBC]
Description = MySQL ODBC 3.51 Driver DSN
Driver = /usr/lib/libmyodbc3.so
Trace = Off
TraceFile = stderr

[MySQL ODBC 3.51 Driver]
DRIVER = /usr/lib/libmyodbc3.so
SETUP = /usr/lib/libmyodbc3S.so
UsageCount = 1

Thursday, January 26, 2006

INSTALL: Installing CURL for PHP (win32)

Assumptions:
PHP folder is C:\PHP
extension folder is C:\PHP\ext
php.ini found in C:\WINDOWS
system32 is C:\WINDOWS\SYSTEM32
web folder is C:\Apache2\htdocs


1. Create a phpinfo.php file in C:\Apache2\htdocs
2. Write <?php echo phpinfo(); ?> as the text of the file phpinfo.php
3. Verify it works: http://localhost/phpinfo.php (should display readonly php.ini in a table). *This confirms that http server works and php is installed
4. At the DOS/Command Prompt type echo %PATH% to view the current path
5. Put C:\PHP and C:\PHP\ext in your path: Go to My Computer->Advanced->Environment Variables->System Variables, and add C:\PHP;C:\PHP\ext; to the end of your path
6. Download the php .zip archive (with all the extensions in it) that corresponds to your version of php and extract libeay32.dll and ssleay32.dll
7. Put libeay32.dll and ssleay32.dll in your C:\WINDOWS\SYSTEM32 folder
8. Verify php_curl.dll is found in your C:\PHP\ext folder
9. Modify C:\WINDOWS\php.ini
- remove semi-colon from line ;php_curl.dll
- in php.ini, verify that extensions_dir = "C:\PHP\ext"
10. Restart HTTP service if you can't tell it worked.
- Start->Control Panel->Administrative Tools->Services
- right click Apache or HTTP or IIS and select restart
11. Verify by checking http://localhost/phpinfo.php
- Curl should have its own spot

Troubleshooting:
If you get the error...
PHP Warning: Unable to load dynamic library 'C:\PHP\ext\php_curl.dll' - The specified module could not be found. in Unknown on line 0
... at the bottom of your http://localhost/phpinfo.php or at the bottom of any php script, then verify that you followed all the steps.

Also, verify that the php.ini you made changes to is the same one that http://localhost/phpinfo.php displays in the fifth (or so) row down under
"Configuration File (php.ini) Path"

Also, verify that you clicked [Apply] or [OK] after step 5

Keep trying stuff until it works.