« August 2002 | Main | October 2002 »

September 29, 2002

First look at DirectX, DirectShow

Played around with DirectX. Goal was to get a handle on how I might automate generating .wmv segments from a list of clips.

It appeared to be necessary to download and install the DirectX SDK 8.1. At least I couldn’t locate the samples refered to in the documentation.

Most of the samples appear to build and run when built by Visual Studio .NET (7.0) instead of with 6.0. I had to build the C:\ProgFiles\DXSDK\samples\Multimedia\DirectShow\BaseClasses project before the TimelineTest project would link. Still not sure one of the Windows XP specific demos will compile. It couldn’t find a header file which is in the DXSDK/include folder.

All this stuff requires working in C++ instead of C#. Drag. No clue on the timeline for a C# compatible release.

Regex and database speed comparisons

The performance of the .NET Framework’s regex implementation seems to be very slow. As is the database writing. Slower than Python.

September 24, 2002

Enabling xml documentation generation and warnings

To generate it, modify the projects properties to add a file name to the Configuration Properties->Build->Xml Documentation File property.

Note, this triggers warnings for all public fields that don’t have documentation strings.

September 23, 2002

recursive source tree checkin script

To recursively check in file in Perforce, wrote the following python script called kzP4Add.py

import os, sys
def visit(arg, dirname, names):
    for n in names:
        r = os.spawnl(os.P_WAIT, r"C:\Program Files\Perforce\p4.exe", r"p4", "add", '"'+os.path.join(dirname, n)+'"')
        print r, dirname, n
def Main():
    if len(sys.argv) != 2:
        print "Usage is kzP4Add "
        for a in sys.argv: print a
        return
    absdir = os.path.abspath(sys.argv[1])
    os.path.walk(absdir, visit, 0)
if __name__ == "__main__":
    Main()

 

Its key that the first argument is the program name, excluding the path info.

Adding the quotes around the filename argument is necessary if the path or name can contain spaces.

The client doesn’t need to be specified.

 

using switches & .config files to control diagnostic output, app.config

Place configuration file contents in a file called app.config in your main project folder.

When the project is built, a copy of the file is automatically generated an named to match the .exe with a “.config” suffix.

 

In the designer properties view setting a DynamicProperties creates an entry in app.config, in the appSettings section. It also adds class field “configurationAppSettings” which is initialized as follows:

System.Configuration.AppSettingsReader configurationAppSettings = new System.Configuration.AppSettingsReader();

 

A “dynamic property” enabled sqlConnection.ConnectionString initializations looks like:

sqlConnection.ConnectionString

= ((string)(configurationAppSettings.GetValue("sqlConnection.ConnectionString", typeof(string))));

 

An alternative all-in-one initialization (not efficient for many, great for just one):

= (string)(new System.Configuration.AppSettingsReader()).GetValue("JobSearchConnectionString", typeof(string));

 

And another way to get the job done that works great for strings:

      = System.Configuration.ConfigurationSettings.AppSettings["JobSearchConnectionString"];

 

For diagnostic switches:

<configuration>

      <system.diagnostics>

            <switches>

                  <add name="DataGridDebugSwitch" value="4"/>

            </switches>

      </system.diagnostics>

</configuration>

 

Declare a TraceSwitch bound by name to the config file.

static TraceSwitch ts = new TraceSwitch("DataGridDebugSwitch", "Control debug output in DataGridColumnStyles");

 

Use the “If” flavor Trace or Debug methods:

Debug.WriteLineIf(ts.TraceInfo, String.Format("LinkLabel constructor id={0}",this.GetHashCode()));

 

The output will only appear if the switch setting is at least as high as the Boolean property chosen for the *If method's predicate argument:

1 == TraceError

2 == TraceWarning

3 == TraceInfo

4 == TraceVerbose

>4, user defined, no bool property.

 

September 22, 2002

Enabling Windows Explorer to search in source files

Note: For the changes below to take effect, loging out and in is sufficient. Restarting Windows Explorer is not.

C# Source (.cs) file contents aren’t searched by default. Set the default text filter with the following saved as a “.reg” file:

 

REGEDIT4

[HKEY_CLASSES_ROOT\.cs\PersistentHandler]

@="{5e941d80-bf96-11cd-b579-08002b30bfeb}"

 

Web Form (.aspx) file contents are filtered in a way that excludes code by default. Set full text search with:

REGEDIT4

[HKEY_CLASSES_ROOT\.aspx\PersistentHandler]

@="{5e941d80-bf96-11cd-b579-08002b30bfeb}"

 

Restore the default handling with:

REGEDIT4

[HKEY_CLASSES_ROOT\.aspx\PersistentHandler]

@=" {eec97550-47a9-11cf-b952-00aa0051fe20}"

 

Getting started with Regex pattern

private static RegexOptions regOpts =

  RegexOptions.Singleline |           // Otherwise “.” doesn’t match newline.

  RegexOptions.IgnoreCase |           // Ignores case of literals in pattern.

  RegexOptions.ExplicitCapture |       // Keeps unnamed parens from adding to groups.

  RegexOptions.Compiled |             // Trades startup time for speed.

  RegexOptions.IgnorePatternWhitespace;    // Allows comments and spacing in pattern for readability.

Regex re = new Regex(@"T(?<tape>\d+)\s+(?<from>\d+-\d+-\d+)\s+to\s+(?<to>\d+-\d+-\d+)\s*", regOpts);

Basic web request & simple spider patterns

CookieContainer cc = new CookieContainer();

// dumpreq.aspx displays param, header, and server variable info to help verify request details.

HttpWebResponse req = (HttpWebRequest)WebRequest.Create("http://localhost/learn/utility/dumpreq.aspx");

// Reuse the same cookie container on multiple requests to accumulate cookies returned with responses.

req.CookieContainer = cc;

// pretend to be IE 6, failing to set a UserAgent often leads to a server error 500 response.

req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705)";

// The following headers are sent by IE 6 but aren’t always necessary…

req.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";

req.Headers.Add("Cache-Control:no-cache");

req.Headers.Add("Accept-Encoding:gzip, deflate");

req.Headers.Add("Accept-Language:en-us");

// To use the post method instead of get, add the following…

req.Method = "POST";

req.ContentType = "application/x-www-form-urlencoded";

string formFields = String.Format("logout=false&goto_event=9685&email=foo@bar.com&password=foobar");

StreamWriter sw = new StreamWriter(req.GetRequestStream()); sw.Write(formFields); sw.Close();

// Submit the request and obtain a response…

HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

// To obtain, html content…

string html = (new StreamReader(req.GetResponse().GetResponseStream())).ReadToEnd();

// To obtain binary content…

byte[] data = (new BinaryReader(req.GetResponse().GetResponseStream())).ReadBytes((int)resp.ContentLength);

FileStream bw = File.Create(“image.jpg”); bw.Write(data, 0, (int)resp.ContentLength); bw.Close();

September 13, 2002

debugging design mode, user controls, custom controls

To debug control design mode (errors occurring when using the design environment), use a second instance of Visual Studio .NET on the same machine.

Start a second Visual Studio .NET, open the same solution you are debugging.

In the original instance (#1), Debug->Processes, select “devenv” process, click Attach. Leave at least “Common Language Runtime” checked. Click OK. Close.

Set appropriate breakpoints in the source files in #1 and/or enable breaking into the debugger on exceptions in #1.

In the second instance (#2), exercise the designer to trigger the error case.

 

September 12, 2002

First brush with the global assembly cache

The global assembly cache under WindowsXP is at c:\windows\assembly

Dragging an assembly into this folder installs it into the global assembly cache. Assembly must have a strong name.

Adding a reference to an assembly in the GAC doesn’t appear to be different than otherwise. Still have to browse to the actual assembly file. It doesn’t appear in the .NET tab’s list of assemblies. Curious.

 

September 11, 2002

Syntax for accessing current value of a DataGrid

grid.BindingContext[grid.DataSource, member].Current

reverse engineering event behaviors, StackTrace

The exact sequence and circumstance of raising events is rarely obvious from the documentation of an object. Here are some tricks for quickly adding instrumentation code to your project prior to experimentally exercising the component.

 

An easy way to track the events being raised:

1. In the designer, double click each event of interest in the Properties->Events view.

2. In the code view, enter the line below in each event handler:

Debug.WriteLine((new StackTrace()).GetFrame(0).GetMethod().Name);

Compact strongly typed collection pattern, CollectionBase

[Serializable]

public class LinkCollection : CollectionBase {

      public LinkCollection() {}

      public LinkCollection(LinkCollection value) {this.AddRange(value);}

      public LinkCollection(Link[] value) {this.AddRange(value);}

      public Link this[int index] {get {return ((Link)(List[index]));} set {List[index] = value;}}

      public int Add(Link value) {return List.Add(value);}

      public void AddRange(Link[] value) {for (int i = 0; i < value.Length; i++) Add(value[i]);}

      public void AddRange(LinkCollection value) {for (int i = 0; i < value.Count; i++) Add(value[i]);}

      public bool Contains(Link value) {return List.Contains(value);}

      public void CopyTo(Link[] array, int index) {List.CopyTo(array, index);}

      public int IndexOf(Link value) {return List.IndexOf(value);}

      public void Insert(int index, Link value) {List.Insert(index, value);}

      public new LinkEnumerator GetEnumerator() {return new LinkEnumerator(this);}

      public void Remove(Link value) {List.Remove(value);}

      public class LinkEnumerator : object, IEnumerator {

            private IEnumerator e; private IEnumerable bc;

            public LinkEnumerator(LinkCollection c) {bc = c; e = bc.GetEnumerator();}

            public Link Current {get {return (Link)e.Current;}}

            public bool MoveNext() {return e.MoveNext();}

            public void Reset() {e.Reset();}

            object IEnumerator.Current {get {return e.Current;}}

            bool IEnumerator.MoveNext() {return e.MoveNext();}

            void IEnumerator.Reset() {e.Reset();}

      }

}

 

 

September 10, 2002

DataGrid, AllowNew, Inhibiting display of append row

from www.syncfusion.com/FAQ, DataGrid

1.       Inhibitting display of append row.

CurrencyManager cm = (CurrencyManager)BindingContext[dataGrid.DataSource, dataGrid.DataMember];     

((DataView)cm.List).AllowNew = false;

 

September 09, 2002

Puzzling out DataGridColumnStyle for LinkLabel behavior

Using the SetDataGridInColumn method to install event handler on the DataGrid for MouseDown and Click events seems to work well.

Because the method gets called multiple times (once per row?) its necessary to avoid adding redundant handlers, they do get called redundantly.

Click events aren’t delivered to the handler for columns which use controls to edit values, the controls absorb all mouse events until the edit completes.

A column such as a LinkLabel column will need to remember the location of the last mousedown and then do a point resolution if a click event occurs. First verify in column, next determine row, finally determine which link, if any was clicked.

Note, using a real LinkLabel control doesn’t seem likely to work. In cell editing usage, a single control is mapped to the active edit cell. It doesn’t seem that a single control without the notion of a column of cells can be helpful to paint all of them and do event registration and delivery.

September 04, 2002

emacs csharp mode setup

Setup csharp-mode.el in emacs:

·         Obtained implementation from http://davh.dk/script/csharp-mode.el

·         Determined that version 21.2 is still latest.

·         Updated _emacs on pell.

September 03, 2002

Configuring Visual Studio "External Tools" to run Ildasm, Emacs, Windows Explorer, and Command Prompt

2002-09-03 10:13 Tue, dotNET, command line compilers, external tools, remoting

Its easy to configure basic development tools to run on the current assembly or source file selected in Visual Studio's Solution Explorer.

 

The “Visual Studio .NET Command Prompt” program menu option sets up the correct environment.

C# compiler is csc. Visual Basic is vbc.

 

Here are the key parameter choices for the basic tools that aren't included in the default configuration. In each case, start with the “External Tools...“ command on the Visual Studio Tools menu.

 

To run Ildasm.exe on the assembly currently selected in the Solution Explorer:

·         C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Bin\ildasm.exe (default installation path).

·         $(TargetPath)

·         $(TargetDir)

 

To run emacs on the source file currently selected in Solution Explorer:

·         C:\ProgFiles\emacs\bin\runemacs.exe (adjust your path to match your emacs installation).

·         $(ItemPath)

·         $(ItemDir)

 

To configure the emacs shell to load vsvars32.bat on startup, modify your emacs startup script as follows:

·         Copy vsvars32.bat from C:\Program Files\Microsoft Visual Studio .NET\Common7\Tools to c:\ProgFiles

·         (setq explicit-cmdproxy.exe-args '("/q /k C:\\ProgFiles\\vsvars32.bat"))

 

To open a command prompt window configured to run visual studio command line tools in the folder containing the currently selected assembly:

·         c:\windows\system32\cmd.exe (default installation path)

·         /k C:\ProgFiles\vsvars32.bat (assumes you copied the file to this location as described above)

·         $(TargetDir)

 

To open a Windows Explorer window to the folder containing the file currently selected in Solution Explorer:

·         c:\windows\explorer.exe

·         $(ItemDir)

web.config file syntax documentation

Web.config file's syntax documentation root is labeled “Configuration File Schema