2009年12月17日 星期四

LINQ and Deploying SQL Server CE 3.5

I have to use INNO Setup to deploy my WPF desktop application with LINQ and SSCE.

On my development desktop, everything is fine. But when I installed the package on another VMs(Win7 and WinXP), it crashed. Then I checked the exception and figured out the reason is connecting DB error. I compared the environment between my development desktop and the VMs. The suspect is Microsoft SQL Server Compact 3.5 SP1 English. It means that I need the runtime of SSCE.

I have 2 choices to solve this problem. One is to install SSCERuntime-ENU-x86.msi during the installation, and the other is to put necessary drivers with AP.

  • Install SSCE runtime during setup

  • In xxx.iss(Inno Setup Script) file, add belows:

    [Files]
    Source: SSCERuntime-ENU-x86.msi; DestDir: {tmp}; Flags: deleteafterinstall

    Besides, we need to add some codes. First, check if SSCE installed.

    RegKeyExists(HKLM, 'Software\Microsoft\Microsoft SQL Server Compact Edition\v3.5');

    If not installed, execute the SSCERuntime-ENU-x86.msi.

    ExtractTemporaryFile('SSCERuntime-ENU-x86.msi');
    Exec('msiexec',ExpandConstant('/i "{tmp}\SSCERuntime-ENU-x86.msi" /qb'),'', SW_SHOW, ewWaitUntilTerminated, ResultCode);

  • Prepare the necessary SSCE drivers

  • Actually, I preper this solution.
    I read "LINQ and Deploying SQL Server CE 3.5" by Matt Sollars on CodeProject and tried so many times, but it didn't work. So if you guys read that article and everything is fine and you could jump this section.

    Besides the 7 dlls that Matt Sollars suggested, I add "System.Data.SqlServerCe.Entity.dll".
    In application config, check the version of System.Data.SqlServerCe
    SSCE_3_5_1
    So, my App.config is:

    <configuration>
    <system.data>
    <DbProviderFactories>
    <remove invariant="System.Data.SqlServerCe.3.5" />
    <add name="Microsoft SQL Server Compact Data Provider"
    invariant="System.Data.SqlServerCe.3.5"
    description=".NET Framework Data Provider for Microsoft SQL Server Compact"
    type="System.Data.SqlServerCe.SqlCeProviderFactory,
    System.Data.SqlServerCe,
    Version=3.5.1.0,
    Culture=neutral,
    PublicKeyToken=89845dcd8080cc91"/>
    </DbProviderFactories>
    </system.data>
    </configuration>

    Finally, don't forget to copy XXX.exe.config to the installation directory.

2009年11月30日 星期一

Exercises : C++ How to Program, Fifth Edition

Developement Environment: Dev-C++ 4.9.9.2


  • 3.11

  • (Modifying Class GradeBook) Modify class GradeBook (Figs. 3.113.12) as follows:
    a. Include a second string data member that represents the course instructor's name.
    b. Provide a set function to change the instructor's name and a get function to retrieve it.
    c. Modify the constructor to specify two parametersone for the course name and one for the instructor's name.
    d. Modify member function displayMessage such that it first outputs the welcome message and course name, then outputs "This course is presented by: " followed by the instructor's name.
    Use your modified class in a test program that demonstrates the class's new capabilities.

    • GradeBook.h


    • #include
      using std::string;

      class GradeBook
      {
      public:
      GradeBook(string, string);
      void setCourseName(string);
      string getCourseName();
      void setCourseInstructorName(string);
      string getCourseInstructorName();
      void displayMessage();

      private:
      string courseName;
      string courseInstructorName;
      };

    • GradeBook.cpp


    • #include
      using std::cout;
      using std::endl;

      #include "GradeBook.h"

      GradeBook::GradeBook(string name, string insName)
      {
      setCourseName(name);
      setCourseInstructorName(insName);
      }

      void GradeBook::setCourseName(string name)
      {
      courseName = name;
      }

      string GradeBook::getCourseName()
      {
      return courseName;
      }

      void GradeBook::setCourseInstructorName(string insName)
      {
      courseInstructorName = insName;
      }

      string GradeBook::getCourseInstructorName()
      {
      return courseInstructorName;
      }

      void GradeBook::displayMessage()
      {
      cout << "Welcome to the grade book for\n" << getCourseName() << "!" <<
      "\nThis course is presented by:" << getCourseInstructorName()
      << endl;
      }

    • main.cpp


    • #include
      using std::cout;
      using std::endl;

      #include "GradeBook.h"

      int main(int argc, char *argv[])
      {
      GradeBook gradeBook1("CS101 Instroduction to C++ Programming", "John");

      gradeBook1.displayMessage();

      system("PAUSE");
      return EXIT_SUCCESS;
      }

    • Output


    • Download Source from here.

  • 3.12

  • (Account Class) Create a class called Account that a bank might use to represent customers' bank accounts. Your class should include one data member of type int to represent the account balance. [Note: In subsequent chapters, we'll use numbers that contain decimal points (e.g., 2.75)called floating-point valuesto represent dollar amounts.] Your class should provide a constructor that receives an initial balance and uses it to initialize the data member. The constructor should validate the initial balance to ensure that it is greater than or equal to 0. If not, the balance should be set to 0 and the constructor should display an error message, indicating that the initial balance was invalid. The class should provide three member functions. Member function credit should add an amount to the current balance. Member function debit should withdraw money from the Account and should ensure that the debit amount does not exceed the Account's balance. If it does, the balance should be left unchanged and the function should print a message indicating "Debit amount exceeded account balance." Member function getBalance should return the current balance. Create a program that creates two Account objects and tests the member functions of class Account.

    • Account.h


    • #include
      using std::string;

      class Account
      {
      public:
      Account(int);
      void credit(int);
      void debit(int);
      int getBalance();

      private:
      int balance;
      };

    • Account.cpp


    • #include
      using std::cout;
      using std::endl;

      #include "Account.h"

      Account::Account(int initAmount)
      {
      if(initAmount < 0)
      {
      balance = 0;
      cout << "ERROR!!! The initial balance was invalid.\n";
      }
      else
      balance = initAmount;

      }

      void Account::credit(int amount)
      {
      balance += amount;
      }

      void Account::debit(int amount)
      {
      if(amount > balance)
      {
      cout << "ERROR!!! Debit amount exceeded account balance.\n";
      return;
      }
      balance -= amount;
      }

      int Account::getBalance()
      {
      return balance;
      }

    • main.cpp


    • #include
      using std::cout;
      using std::endl;

      #include "Account.h"

      int main(int argc, char *argv[])
      {
      Account acct1(-10);
      cout << "Acct 1, Balance => $" << acct1.getBalance() << "\n";
      acct1.credit(100);
      cout << "Acct 1, Balance => $" << acct1.getBalance() << "\n";


      Account acct2(1000);
      cout << "Acct 2, Balance => $" << acct2.getBalance() << "\n";
      acct2.debit(2000);
      cout << "Acct 2, Balance => $" << acct2.getBalance() << "\n";

      system("PAUSE");
      return EXIT_SUCCESS;
      }

    • Output


    • Download source from here.

  • 9.6

  • (Rational Class) Create a class called Rational for performing arithmetic with fractions. Write a program to test your class.
    Use integer variables to represent the private data of the classthe numerator and the denominator. Provide a constructor that enables an object of this class to be initialized when it is declared. The constructor should contain default values in case no initializers are provided and should store the fraction in reduced form. For example, the fraction

    would be stored in the object as 1 in the numerator and 2 in the denominator. Provide public member functions that perform each of the following tasks:

    a. Adding two Rational numbers. The result should be stored in reduced form.
    b. Subtracting two Rational numbers. The result should be stored in reduced form.
    c. Multiplying two Rational numbers. The result should be stored in reduced form.
    d. Dividing two Rational numbers. The result should be stored in reduced form.
    e. Printing Rational numbers in the form a/b, where a is the numerator and b is the denominator.
    f. Printing Rational numbers in floating-point format.

    • TBD


2009年11月27日 星期五

WPF DataGrid

1. Create a WPF Application through Visual Studio 2008 SP1 and Dot Net Framework 3.5 SP1.

In Windows1.xaml

< Window x:Class="WpfDataGrid.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
Title="Window1" Height="300" Width="600">




< dg:DataGridTextColumn Header="First Name" Binding="{Binding Path=FirstName}"/>
< dg:DataGridTextColumn Header="Last Name" Binding="{Binding Path=LastName}"/>
< dg:DataGridTextColumn Header="Address" Binding="{Binding Path=Address}"/>
< dg:DataGridCheckBoxColumn Header="New?" Binding="{Binding Path=IsNew}"/>
< dg:DataGridCheckBoxColumn Header="Subscribed?" Binding="{Binding Path=IsSubscribed}"/>







In Windows1.xaml.cs
First, define a class to generate data to display.

public class Customer
{
public String FirstName { get; set; }
public String LastName { get; set; }
public String Address { get; set; }
public Boolean IsNew { get; set; }

// A null value for IsSubscribed can indicate
// "no preference" or "no response".
public Boolean? IsSubscribed { get; set; }

public Customer(String firstName, String lastName,
String address, Boolean isNew, Boolean? isSubscribed)
{
this.FirstName = firstName;
this.LastName = lastName;
this.Address = address;
this.IsNew = isNew;
this.IsSubscribed = isSubscribed;
}

public static ObservableCollection GetSampleCustomerList()
{
return new ObservableCollection (new Customer[4] {
new Customer("A.", "Zero",
"12 North Third Street, Apartment 45",
false, true),
new Customer("B.", "One",
"34 West Fifth Street, Apartment 67",
false, false),
new Customer("C.", "Two",
"56 East Seventh Street, Apartment 89",
true, null),
new Customer("D.", "Three",
"78 South Ninth Street, Apartment 10",
true, true)
});
}
}


By this way, we could see the simple WPF DataGrid.


Run this program, one problem occured. If you would like to change the status of the checkbox, you have to click twice. First click will focus on the row, and second click will change the state of the checkbox.
The solution is to use DataGridTemplateColumn to replace the DataGridCheckBoxColumn.

















At this moment, everything seems to be ok. But in practice, if we could not make sure how many columns we have, what should we do?
So we need to create DataGrid programmatically.

In Windows1.xaml, we don't need the defination of the columns, just leave the declaration of < dg:DataGrid/>.

< Window x:Class="WpfDataGrid.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dg="http://schemas.microsoft.com/wpf/2008/toolkit"
Title="Window1" Height="300" Width="600">


< dg:DataGrid AutoGenerateColumns="False" Margin="22,24,20,26" Name="dataGrid"/>





In Windows.xaml.cs, I wrote a method InitDataGrid and put it after InitializeComponent().

private void InitDataGrid()
{
dataGrid.ItemsSource = Customer.GetSampleCustomerList();

dataGrid.Columns.Clear();

dataGrid.Columns.Add(GetTextColumn("First Name", "FirstName"));
dataGrid.Columns.Add(GetTextColumn("Last Name", "LastName"));
dataGrid.Columns.Add(GetTextColumn("Address", "Address"));
dataGrid.Columns.Add(GetCheckBoxColumn("New?", "IsNew"));
dataGrid.Columns.Add(GetCheckBoxColumn("Subscribed?", "IsSubscribed"));
}


private DataGridTextColumn GetTextColumn(string _header, string _binding)
{
DataGridTextColumn col = new DataGridTextColumn();
col.Header = _header;
if (_binding != null && _binding != "")
col.Binding = GetBinding(_binding, BindingMode.OneWay);
return col;
}


private DataGridTemplateColumn GetCheckBoxColumn(string _header, string _binding)
{
DataGridTemplateColumn col = new DataGridTemplateColumn();
col.Header = _header;

Dictionary values = new Dictionary();
//values.Add(CheckBox.StyleProperty, FindResource("DataGridCheckBoxStyle"));

Dictionary bindings = new Dictionary();
bindings.Add(CheckBox.IsCheckedProperty, GetBinding(_binding, BindingMode.TwoWay));

col.CellTemplate = GetDataTemplate(typeof(CheckBox), values, bindings);
return col;
}


private DataTemplate GetDataTemplate(Type _t, Dictionary _values,
Dictionary _bindings)
{
DataTemplate dt = new DataTemplate();
FrameworkElementFactory factory = new FrameworkElementFactory(_t);
dt.VisualTree = factory;
//SetValue
foreach (KeyValuePair kvp in _values)
{
factory.SetValue(kvp.Key, kvp.Value);
}
//SetBinding
foreach (KeyValuePair kvp in _bindings)
{
factory.SetBinding(kvp.Key, kvp.Value);
}
return dt;
}


private Binding GetBinding(string _path, BindingMode _mode)
{
Binding binding = new Binding();
binding.Path = new PropertyPath(_path);
binding.Mode = _mode;
return binding;
}


You could download the solution from here.
If you use Firefox, you may see strange syntax. If so, try to use IE or just download the source code.

2009年11月26日 星期四

C# Timestamp

1.Define a class, HiResDateTime

public class HiResDateTime
{
private static DateTime _startTime;
private static System.Diagnostics.Stopwatch _stopWatch = null;
private static TimeSpan _maxIdle = TimeSpan.FromSeconds(10);

public static DateTime UtcNow
{
get
{
if ((_stopWatch == null) ||
(_startTime.Add(_maxIdle) < DateTime.UtcNow))
{
Reset();
}
return _startTime.AddTicks(_stopWatch.Elapsed.Ticks);
}
}

private static void Reset()
{
_startTime = DateTime.UtcNow;
_stopWatch = System.Diagnostics.Stopwatch.StartNew();
}
}


2.How to use:

Console.WriteLine("{0}", HiResDateTime.UtcNow.ToString("yyyyMMddHHmmssffff"));

2009年11月21日 星期六

WRONG HOLE with DJ Lubel, Taryn Southern and Scott Baio



I took her on a date things seemed so bright
I knew I would not need my youporn tonight
We go to her place and we fooled around
We throw all our clothes to the ground

We begin as she turns out the lights
I start but feel something so very extra tight
I hear her cry and I see her frown
I look at the condom it is all brown

Last night I stuck it in the wrong hole
I'm so sorry from the bottom of my soul
Cause I stuck it in the wrong hole

Try some preparation H it'll make you feel better
In my defense those holes are so close together
Oh baby baby don't feel defiled
It's a common accident during doggy style

It was so dark I couldn't see so good
I had no idea where I put my wood
I want to make things better want to make it alright
If you want you can put on a strap on and give it back to me all night ( I'd rather if she didn't)

Last night I stuck it in the wrong hole
I'm so sorry from the bottom of my soul

I never ever want to make you feel hurting
I guess that's why God made that hole not for inserting
Tell me how you feel baby please don't pause
Now I know how they feel in that HBO show OZ
Maybe take some advit your pain it will fix
From the way you are walking you can compete in the special olympics
If this was Alabama we would be on trial
That's how my mom took my temperature when I was a child

I've got a confession and I think you wont mind
I kinda liked when you put it in my behind
I don't know baby I'm no Sodomite
Can't we just try it again tonight?

Alright!

Every night I stick it in the wrong hole
It's so much fun and we don't need no birth control
When we stick it in the wrong hole.

I stuck in your ass.

2009年11月13日 星期五

C# Thread Implementation

I will demonstrate 3 types of thread implementations in C#. They are ThreadPool.QueueUserWorkItem(), Thread, and Win32 thread.

1. ThreadPool.QueueUserWorkItem

class Program
{
static void Main(string[] args)
{
string message = "Hi";
ThreadPool.QueueUserWorkItem(DoSomething, message);
}

//The method to be used in ThreadPool.QueueUserWorkItem, must has one parameter
//with object
static void DoSomething(object stateInfo)
{
Console.WriteLine("DoSomething: stateInfo={0}", stateInfo.ToString());
}
}


2. Thread
First, create a Daemon class. This class has a constructor with values. Besides, it has a delegate callback function.

public class Daemon
{
private string title;
private int val;

private DelegateCallbackFunc callback;

public Daemon(string _title, int _val, DelegateCallbackFunc _callback)
{
title = _title;
val = _val;
callback = _callback;
}

public void DoSomething()
{
try
{
Console.WriteLine("DoSomething: _title={0}, _val={1}", title, val);
title = title + " Dude!";
val = val + 1;

//Callback
if (callback != null)
callback(title, val);
}
catch (ThreadAbortException ex)
{

}
finally
{

}

}
}

//Declare a delegate callback method
public delegate void DelegateCallbackFunc(string _title, int _val);

Second, create and start the thread.

class Program
{
static void Main(string[] args)
{
Daemon d = new Daemon("Hi", 0, new DelegateCallbackFunc(CallbackFunc));
Thread t = new Thread(new ThreadStart(d.DoSomething));
t.Start();
}

public static void CallbackFunc(string _title, int _val)
{
Console.WriteLine("CallbackFunc: _title={0}, _val={1}", _title, _val);
}
}

3. Use win32 thread
First, create a class with extern declaration.

public class Win32
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CreateThread(ref SECURITY_ATTRIBUTES lpThreadAttributes,
int dwStackSize, Delegate lpStartAddress, ref object lpParameter,
int dwCreationFlags, ref int lpThreadId);

[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
}

public delegate void ExecuteFunc();

Second, use this Win32 class in main program.

class Program
{
static void Main(string[] args)
{
Daemon d = new Daemon("Hi", 0, new DelegateCallbackFunc(CallbackFunc));
ExecuteFunc ef = new ExecuteFunc(d.DoSomething);

Win32.SECURITY_ATTRIBUTES sa = new Win32.SECURITY_ATTRIBUTES();
object lpParameter = new object();
int lpThreadId = 0;
Win32.CreateThread(ref sa, 0, ef, ref lpParameter, 0, ref lpThreadId);
}
}


Source code is here.

2009年9月16日 星期三

C# byte[] string Convert

byte[] → string

byte[] byteArr = new byte[]{1,0};
string s = System.Text.Encoding.ASCII.GetString(byteArr);

string → byte[]

System.Text.Encoding.ASCII.GetBytes(s);

2009年8月29日 星期六

2009/08/29 汐止←→五分山氣象站

去程:汐止→汐平公路→平溪→106縣道(十分、74.5公里處五分山氣象站入口)→五分山氣象站

回程:五分山氣象站→106縣道(十分、平溪)→汐平公路→汐止

總里程:74.99KM
總騎乘時間:5:28:44

行程圖片




2009年8月18日 星期二

Java HashMap VS C# Dictionary



Java Code:

HashMap< String , String > hm = new HashMap< String , String >();
hm.put("A", "A--Content");
hm.put("B", "B--Content");
//Get all value
for(Iterator< String > it = hm.keySet().iterator(); it.hasNext();){
String key = it.next();
System.out.println("Key: "+ key + ", value: "+hm.get(key));
}
//Get specific value
System.out.println(hm.get("A"));


C# Code:

Dictionary< string , string > dict = new Dictionary< string , string >();
try
{
dict.Add("A", "A--Content");
dict.Add("B", "B--Content");
//Get all value
foreach (KeyValuePair< string , string > kvp in dict)
{
Console.WriteLine("key: {0}, value: {1}", kvp.Key, kvp.Value);
}
//Get specific value
string val = "";
dict.TryGetValue("A", out val);
Console.WriteLine("value="+val);
//or
Console.WriteLine("value=" + dict["A"]);
}
catch (Exception)
{
//The method "Add" will throw exception if key already existed!!!
Console.WriteLine("Can't insert same key");
}

2009年8月2日 星期日

8/2 汐止 ←→ 冷水坑

去程:汐止→河濱自行車專用道(汐止→東湖→南港→松山→內湖→大直)→大直美麗華→劍南路至善路三段71巷平菁街(平等國小→台北奧萬大)→菁山路菁山路101巷→冷水坑

回程:原路折返

心得:冷水坑真的很不好騎,連續的超陡坡,不過從至善路三段71巷開始至終點冷水坑,不落地完成。


總騎乘距離:78.53 KM
總騎乘時間:5:45:26

2009年4月13日 星期一

jQuery AJAX on IE does not reflesh

If you use jQuery to implement the AJAX functionality, especially use the "get", "getJSON" and "load", would you encounter one problem on IE, "Ajax" does not really call backend link, but return value immediately".

The problem is the cache of IE. If we use "Get" method to get data from backend, and the parameters are the same, IE won't really get the data. In contrast, FF does not have this problem. The solution is to set cache to false.


$.ajaxSetup({cache: false});
$.get("xxx.jsp",{A=a,B=b},function(){

});


Or, add a parameter with date.

$.get("xxx.jsp",{timestamp:new Date().getTime()},function(){

});

Subversion on Win2000 Server

New subversion does not support Windows 2000. So we need to use the older version, 1.4.6.

After the installation of SVN, following the steps below:

  1. Create repository


  2. cd C:\Subversion\bin\
    svnadmin create D:\Repos

  3. Configuration

  4. svnserve.conf

    [general]
    anon-access = read #If you meet
    #"svn: Not authorized to open root of edit operation"
    #change read to none
    auth-access = write #write means read and write

    password-db = passwd #file "passwd"

    authz-db = authz #file "authz"

    realm = My Project #You could change this as you want.

    passwd

    [users]
    austin = austin
    ting = ting # userid = password

    authz

    [groups]
    matrix = austin,ting # group_name = group_members, ....

    [Repos:/] # The repository you create before.
    # or [/] for each repository
    @matrix = rw # @+group_name, rw => read and write

  5. Start the SVN Server


  6. cd C:\Subversion\bin\
    svnserve -d

2009年4月4日 星期六

汐止 ←→ 小油坑

去程:
汐止國泰醫院 → 大同路 → 中興路 → 自行車專用道 → 內湖出水門 → 基湖路 → 內湖路 → 明水路 → 自強隧道 → 至善路 → 仰德大道 → 陽金公路 → 小油坑

回程:
小油坑 → 陽金公路 → 仰德大道 → 至善路 → 劍南路 → 美麗華 → 自行車專用道 → 中興路 → 大同路 → 汐止國泰醫院


P.S 去程出錯水門,多繞了一下;回程繞劍南路,沒想到坡還頗硬,邊踩還邊怕抽筋。

路程 77.90 KM,實際騎乘時間 5:00:47

心得:
  1. 走了無意義的汐止到至善路,浪費一堆體力,有4+2會更好
  2. 上山體力耗損超快,就算早餐吃很飽也是無濟於事,路上一定要再吃點東西補充體力
  3. 變速線及煞車線外管保護套,很不牢固,裝三個,此行就掉兩個
  4. 我的安全帽不適合,回程頭痛欲裂 (這是一個敗家的好理由...)
  5. 下山的時候兩隻大腿同時抽筋,只要打直就會抽,也算是一個新鮮的體驗啦
  6. 肚子餓好解決,腿力不夠無解,即便是輕量化爬坡輪組也救不了你,看來練腿力才是王道