Nice!
FWIW, it looks like the TABS got a bit messed up on pasting - in general don't paste directly from VS 2005, but rather from emacs or notepad and use the "F#" button on the editing toolbar. (You may have to be logged in to get access to that - I'm not sure if that's still the case)
Here's a version of the code using more standard F# formatting, including the #light syntax. I've also made a few other modifications, e.g. the use of .Add to wire up event handlers, and the use of "|> ignore". Also I'm not sure it's necessary to create a new buffer each time around the reading loops.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
#light open System open System.Collections.Generic open System.ComponentModel open System.Data open System.Drawing open System.Text open System.Windows.Forms open System.IO open System.Diagnostics open System.Threading type MainForm = class inherit System.Windows.Forms.Form as base override this.Dispose(disposing) = if (disposing && (match this.components with null -> false | _ -> true)) then this.components.Dispose(); base.Dispose(disposing) member this.InitializeComponent() = this.tbWorkArea <- new System.Windows.Forms.TextBox(); this.proc <- new System.Diagnostics.Process(); this.msMain <- new System.Windows.Forms.MenuStrip(); this.fileToolStripMenuItem <- new System.Windows.Forms.ToolStripMenuItem(); this.saveToolStripMenuItem <- new System.Windows.Forms.ToolStripMenuItem(); this.openToolStripMenuItem <- new System.Windows.Forms.ToolStripMenuItem(); this.exitToolStripMenuItem <- new System.Windows.Forms.ToolStripMenuItem(); this.workspaceToolStripMenuItem <- new System.Windows.Forms.ToolStripMenuItem(); this.fontToolStripMenuItem <- new System.Windows.Forms.ToolStripMenuItem(); this.textColorToolStripMenuItem <- new System.Windows.Forms.ToolStripMenuItem(); this.backgroundColorToolStripMenuItem <- new System.Windows.Forms.ToolStripMenuItem(); this.sfdSave <- new System.Windows.Forms.SaveFileDialog(); this.ofdOpen <- new System.Windows.Forms.OpenFileDialog(); this.cdColor <- new System.Windows.Forms.ColorDialog(); this.fdFont <- new System.Windows.Forms.FontDialog(); this.msMain.SuspendLayout(); this.SuspendLayout(); // // tbWorkArea // this.tbWorkArea.Dock <- System.Windows.Forms.DockStyle.Fill; this.tbWorkArea.Font <- new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, Convert.ToByte(0)); this.tbWorkArea.Location <- new System.Drawing.Point(0, 24); this.tbWorkArea.Multiline <- true; this.tbWorkArea.Name <- "tbWorkArea"; this.tbWorkArea.Size <- new System.Drawing.Size(566, 377); this.tbWorkArea.TabIndex <- 0; this.tbWorkArea.WordWrap <- false; this.tbWorkArea.KeyUp.Add(fun e -> this.tbWorkArea_KeyUp e); // // proc // this.proc.StartInfo.Domain <- ""; this.proc.StartInfo.LoadUserProfile <- false; this.proc.StartInfo.Password <- null; // this.proc.StartInfo.StandardErrorEncoding <- null; // this.proc.StartInfo.StandardOutputEncoding <- null; this.proc.StartInfo.UserName <- ""; this.proc.SynchronizingObject <- this; // // msMain // // new System.Windows.Forms.ToolStripItem[] this.msMain.Items.AddRange([| (this.fileToolStripMenuItem :> System.Windows.Forms.ToolStripItem) ; (this.workspaceToolStripMenuItem :> System.Windows.Forms.ToolStripItem) |]); this.msMain.Location <- new System.Drawing.Point(0, 0); this.msMain.Name <- "msMain"; this.msMain.Size <- new System.Drawing.Size(566, 24); this.msMain.TabIndex <- 1; this.msMain.Text <- "menu"; // // fileToolStripMenuItem // // new System.Windows.Forms.ToolStripItem[] this.fileToolStripMenuItem.DropDownItems.AddRange([|(this.saveToolStripMenuItem:>System.Windows.Forms.ToolStripItem); (this.openToolStripMenuItem:>System.Windows.Forms.ToolStripItem); (this.exitToolStripMenuItem:>System.Windows.Forms.ToolStripItem)|]); this.fileToolStripMenuItem.Name <- "fileToolStripMenuItem"; this.fileToolStripMenuItem.Size <- new System.Drawing.Size(35, 20); this.fileToolStripMenuItem.Text <- "&File"; // // saveToolStripMenuItem // this.saveToolStripMenuItem.Name <- "saveToolStripMenuItem"; this.saveToolStripMenuItem.ShortcutKeys <- unbox(box(unbox(box(System.Windows.Forms.Keys.Control)) lor unbox(box(System.Windows.Forms.Keys.S)))); // this.saveToolStripMenuItem.ShortcutKeys <- (unbox(box(131072 lor 83))); this.saveToolStripMenuItem.Size <- new System.Drawing.Size(140, 22); this.saveToolStripMenuItem.Text <- "&Save"; this.saveToolStripMenuItem.Click.Add(fun e -> this.saveToolStripMenuItem_Click e); // // openToolStripMenuItem // this.openToolStripMenuItem.Name <- "openToolStripMenuItem"; this.openToolStripMenuItem.ShortcutKeys <- unbox(box(unbox(box(System.Windows.Forms.Keys.Control)) lor unbox(box(System.Windows.Forms.Keys.O)))); this.openToolStripMenuItem.Size <- new System.Drawing.Size(140, 22); this.openToolStripMenuItem.Text <- "&Open"; this.openToolStripMenuItem.Click.Add(fun e -> this.openToolStripMenuItem_Click e); // // exitToolStripMenuItem // this.exitToolStripMenuItem.Name <- "exitToolStripMenuItem"; this.exitToolStripMenuItem.Size <- new System.Drawing.Size(140, 22); this.exitToolStripMenuItem.Text <- "E&xit"; this.exitToolStripMenuItem.Click.Add(fun e -> this.exitToolStripMenuItem_Click e); // // workspaceToolStripMenuItem // // new System.Windows.Forms.ToolStripItem[] this.workspaceToolStripMenuItem.DropDownItems.AddRange ([| (this.fontToolStripMenuItem:>System.Windows.Forms.ToolStripItem); (this.textColorToolStripMenuItem:>System.Windows.Forms.ToolStripItem); (this.backgroundColorToolStripMenuItem:>System.Windows.Forms.ToolStripItem)|]); this.workspaceToolStripMenuItem.Name <- "workspaceToolStripMenuItem"; this.workspaceToolStripMenuItem.Size <- new System.Drawing.Size(72, 20); this.workspaceToolStripMenuItem.Text <- "&Workspace"; // // fontToolStripMenuItem // this.fontToolStripMenuItem.Name <- "fontToolStripMenuItem"; this.fontToolStripMenuItem.Size <- new System.Drawing.Size(158, 22); this.fontToolStripMenuItem.Text <- "F&ont"; this.fontToolStripMenuItem.Click.Add(fun e -> this.fontToolStripMenuItem_Click e); // // textColorToolStripMenuItem // this.textColorToolStripMenuItem.Name <- "textColorToolStripMenuItem"; this.textColorToolStripMenuItem.Size <- new System.Drawing.Size(158, 22); this.textColorToolStripMenuItem.Text <- "&Text Color"; this.textColorToolStripMenuItem.Click.Add(fun e -> this.textColorToolStripMenuItem_Click e); // // backgroundColorToolStripMenuItem // this.backgroundColorToolStripMenuItem.Name <- "backgroundColorToolStripMenuItem"; this.backgroundColorToolStripMenuItem.Size <- new System.Drawing.Size(158, 22); this.backgroundColorToolStripMenuItem.Text <- "&Background Color"; this.backgroundColorToolStripMenuItem.Click.Add(fun e -> this.backgroundColorToolStripMenuItem_Click e); // // sfdSave // this.sfdSave.CheckFileExists <- true; this.sfdSave.FileOk.Add(fun e -> this.sfdSave_FileOk e); // // ofdOpen // this.ofdOpen.FileName <- "openFileDialog1"; this.ofdOpen.FileOk.Add(fun e -> this.ofdOpen_FileOk e); // // MainForm // this.AutoScaleDimensions <- new System.Drawing.SizeF(Convert.ToSingle(6), Convert.ToSingle(13)); this.AutoScaleMode <- System.Windows.Forms.AutoScaleMode.Font; this.ClientSize <- new System.Drawing.Size(566, 401); this.Controls.Add(this.tbWorkArea); this.Controls.Add(this.msMain); this.MainMenuStrip <- this.msMain; this.Name <- "MainForm"; this.Text <- "MainForm"; this.FormClosing.Add(fun e -> this.MainForm_FormClosing e); this.msMain.ResumeLayout(false); this.msMain.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); val mutable tbWorkArea : System.Windows.Forms.TextBox; val mutable proc : System.Diagnostics.Process; val mutable msMain : System.Windows.Forms.MenuStrip; val mutable fileToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem; val mutable saveToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem; val mutable exitToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem; val mutable openToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem; val mutable sfdSave : System.Windows.Forms.SaveFileDialog; val mutable ofdOpen : System.Windows.Forms.OpenFileDialog; val mutable workspaceToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem; val mutable textColorToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem; val mutable backgroundColorToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem; val mutable cdColor : System.Windows.Forms.ColorDialog; val mutable fontToolStripMenuItem : System.Windows.Forms.ToolStripMenuItem; val mutable fdFont : System.Windows.Forms.FontDialog; val mutable bookmark : System.Int32; val mutable components: System.ComponentModel.Container; val mutable writer : System.Threading.Thread; val mutable reader : System.Threading.Thread; val mutable err_reader : System.Threading.Thread; val mutable stop : System.Threading.ManualResetEvent; member this.tbWorkArea_KeyUp (e : KeyEventArgs) = if (e.KeyData = Keys.Enter) then let mutable toWrite = "" if (this.bookmark < this.tbWorkArea.Text.Length) then toWrite <- this.tbWorkArea.Text.Substring(this.bookmark); this.proc.StandardInput.Write(toWrite); if (this.bookmark >= this.tbWorkArea.Text.Length) then this.bookmark <- this.tbWorkArea.Text.Length; member this.saveToolStripMenuItem_Click (e:EventArgs) = this.sfdSave.ShowDialog() |> ignore member this.openToolStripMenuItem_Click (e:EventArgs) = this.ofdOpen.ShowDialog() |> ignore member this.exitToolStripMenuItem_Click (e:EventArgs) = this.Close() member this.fontToolStripMenuItem_Click (e:EventArgs) = if (this.fdFont.ShowDialog() = DialogResult.OK) then this.tbWorkArea.Font <- this.fdFont.Font member this.textColorToolStripMenuItem_Click (e:EventArgs) = if (this.cdColor.ShowDialog() = DialogResult.OK) then this.tbWorkArea.ForeColor <- this.cdColor.Color member this.backgroundColorToolStripMenuItem_Click (e:EventArgs) = if (this.cdColor.ShowDialog() = DialogResult.OK) then this.tbWorkArea.BackColor <- this.cdColor.Color member this.sfdSave_FileOk (e:CancelEventArgs) = let sw = new StreamWriter(this.sfdSave.FileName) sw.Write(this.tbWorkArea.Text); sw.Close(); sw.Dispose() member this.ofdOpen_FileOk (e:CancelEventArgs) = let sr = new StreamReader(this.ofdOpen.FileName) let cod = sr.ReadToEnd() sr.Close(); this.tbWorkArea.AppendText(cod) member this.MainForm_FormClosing (e:FormClosingEventArgs) = this.DoOnExit() member this.DoOnStart() = let psi = new ProcessStartInfo() this.tbWorkArea.ForeColor <- Color.FromArgb(255, 0, 0, 160); this.tbWorkArea.BackColor <- Color.FromArgb(255, 192, 192, 192); psi.FileName <- "ocaml"; psi.CreateNoWindow <- true; psi.RedirectStandardError <- true; //This was the cause that some responses could not be seen. psi.RedirectStandardInput <- true; psi.RedirectStandardOutput <- true; psi.UseShellExecute <- false; this.proc.StartInfo <- psi; this.proc.Start(); |> ignore; this.stop <- new ManualResetEvent(false); this.reader <- new Thread(new ThreadStart(fun x -> this.readerMtd())); this.writer <- new Thread(new ThreadStart(fun x -> this.writerMtd())); this.err_reader <- new Thread(new ThreadStart(fun x -> this.err_readerMtd())); this.reader.Start(); this.writer.Start(); this.err_reader.Start() member this.readerMtd() = let MAX_BUF = 4096 let lbuffer = Array.create MAX_BUF '0' //char[] let mutable bread = 0 while not (this.stop.WaitOne(1, true)) do try bread <- this.proc.StandardOutput.Read(lbuffer, 0, MAX_BUF); while (bread > 0) do this.AppendText(new string(lbuffer, 0, bread)); bread <- this.proc.StandardOutput.Read(lbuffer, 0, MAX_BUF); done; with | :?NullReferenceException -> (); | _ -> (); done; member this.err_readerMtd() = let MAX_BUF = 4096 let lbuffer = Array.create MAX_BUF '0' let mutable bread = 0 while not (this.stop.WaitOne(1, true)) do try bread <- this.proc.StandardError.Read(lbuffer, 0, MAX_BUF); while (bread > 0) do this.AppendText(new string(lbuffer, 0, bread)); bread <- this.proc.StandardError.Read(lbuffer, 0, MAX_BUF); done; with | :? NullReferenceException -> (); | _ -> (); done; member this.writerMtd() = () new () as this = { tbWorkArea = null; proc = null; msMain = null; fileToolStripMenuItem = null; saveToolStripMenuItem = null; exitToolStripMenuItem = null; openToolStripMenuItem = null; sfdSave = null; ofdOpen = null; workspaceToolStripMenuItem = null; textColorToolStripMenuItem = null; backgroundColorToolStripMenuItem = null; cdColor = null; fontToolStripMenuItem = null; fdFont = null; bookmark = 0; components = null; writer = null; reader = null; err_reader = null; stop = null;} then this.InitializeComponent(); this.sfdSave.Filter <- "ML files (*.ml)|*.ml|MLI files (*.mli)|*.mli|All Files (*.*)|*.*"; this.ofdOpen.Filter <- "ML files (*.ml)|*.ml|MLI files (*.mli)|*.mli|All Files (*.*)|*.*"; this.DoOnStart(); member this.AppendText(text) = let fd = new Converter<_,_>(fun latext -> this.AppendText(latext)) if (this.tbWorkArea.InvokeRequired) then this.Invoke(fd, [|box(text)|]) |> ignore else this.tbWorkArea.AppendText(text) this.bookmark <- this.tbWorkArea.Text.Length; member this.DoOnExit() = this.stop.Set() |> ignore try this.proc.StandardError.Close(); with | _ -> (); try this.proc.StandardInput.Close(); with | _ -> (); try this.proc.StandardOutput.Close(); with | _ -> (); try if not (this.proc.WaitForExit(200)) then this.proc.Kill(); this.proc.Close(); with | _ -> (); try if not (this.reader.Join(200)) then this.reader.Abort(); with | _ -> (); try if not (this.err_reader.Join(200)) then this.err_reader.Abort(); with | _ -> (); try if not (this.writer.Join(200)) then this.writer.Abort(); with | _ -> (); end [<STAThread>] let main() = Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Thread.Sleep(400); Application.Run(new MainForm()); [<STAThread>] do main()
Thank you for a very educational, great sample. I've taken the liberty to revamp it a little. Specifically, I changed the following:
- Fixed the clean-up code in DoOnExit: the exception patterns bind more tightly than sequencing, so unless an exception is thrown, latter code doesn't get executed. I've used a higher-order function, swallow, with a form reminiscent of ignore.
- Added detection of process exiting to close the form.
- Abstracted the reading code for stdin and stdout into a common, ThreadStart-returning method.
- Used Enum.Combine to simplify adding accelerator keys to menu items.
- Used Idioms.using around some IDisposable acquisitions.
- Re-formatted the code a little to make it a bit more idiomatic F#/ML.
I've found the code instructive, and I wanted to share what I've learned. Thank you.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
open System open System.Collections.Generic open System.ComponentModel open System.Data open System.Drawing open System.Text open System.Windows.Forms open System.IO open System.Diagnostics open System.Threading let ml_pattern_filter = "ML files (*.ml)|*.ml|MLI files (*.mli)|*.mli|All Files (*.*)|*.*" let swallow (thunk : unit -> unit) = try thunk () with _ -> () type MainForm = class inherit System.Windows.Forms.Form as base val mutable tbWorkArea : System.Windows.Forms.TextBox val mutable proc : System.Diagnostics.Process val mutable msMain : System.Windows.Forms.MenuStrip val mutable miFile : System.Windows.Forms.ToolStripMenuItem val mutable miSave : System.Windows.Forms.ToolStripMenuItem val mutable miOpen : System.Windows.Forms.ToolStripMenuItem val mutable miExit : System.Windows.Forms.ToolStripMenuItem val mutable miWorkspace : System.Windows.Forms.ToolStripMenuItem val mutable miFont : System.Windows.Forms.ToolStripMenuItem val mutable miTextColor : System.Windows.Forms.ToolStripMenuItem val mutable miBackColor : System.Windows.Forms.ToolStripMenuItem val mutable sfdSave : System.Windows.Forms.SaveFileDialog val mutable ofdOpen : System.Windows.Forms.OpenFileDialog val mutable cdColor : System.Windows.Forms.ColorDialog val mutable fdFont : System.Windows.Forms.FontDialog val mutable bookmark : System.Int32 val mutable stdoutReader : System.Threading.Thread val mutable stderrReader : System.Threading.Thread val mutable stopSignal : System.Threading.ManualResetEvent val mutable components: System.ComponentModel.Container new () as this = { tbWorkArea = null; proc = null; msMain = null; miFile = null; miSave = null; miExit = null; miOpen = null; sfdSave = null; ofdOpen = null; miWorkspace = null; miTextColor = null; miBackColor = null; cdColor = null; miFont = null; fdFont = null; bookmark = 0; components = null; stdoutReader = null; stderrReader = null; stopSignal = null; } then this.InitializeComponent (); this.DoOnStart () override this.Dispose disposing = if disposing && this.components <> null then this.components.Dispose (); base.Dispose disposing member this.InitializeComponent () = this.tbWorkArea <- new System.Windows.Forms.TextBox (); this.proc <- new System.Diagnostics.Process (); this.msMain <- new System.Windows.Forms.MenuStrip (); this.miFile <- new System.Windows.Forms.ToolStripMenuItem (); this.miSave <- new System.Windows.Forms.ToolStripMenuItem (); this.miOpen <- new System.Windows.Forms.ToolStripMenuItem (); this.miExit <- new System.Windows.Forms.ToolStripMenuItem (); this.miWorkspace <- new System.Windows.Forms.ToolStripMenuItem (); this.miFont <- new System.Windows.Forms.ToolStripMenuItem (); this.miTextColor <- new System.Windows.Forms.ToolStripMenuItem (); this.miBackColor <- new System.Windows.Forms.ToolStripMenuItem (); this.sfdSave <- new System.Windows.Forms.SaveFileDialog (); this.ofdOpen <- new System.Windows.Forms.OpenFileDialog (); this.cdColor <- new System.Windows.Forms.ColorDialog (); this.fdFont <- new System.Windows.Forms.FontDialog (); this.msMain.SuspendLayout (); this.SuspendLayout (); // // tbWorkArea // this.tbWorkArea.Dock <- System.Windows.Forms.DockStyle.Fill; this.tbWorkArea.Font <- new System.Drawing.Font ("Courier New", 8.F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, Convert.ToByte 0); this.tbWorkArea.Location <- new System.Drawing.Point (0, 24); this.tbWorkArea.Multiline <- true; this.tbWorkArea.ScrollBars <- System.Windows.Forms.ScrollBars.Vertical; this.tbWorkArea.Name <- "tbWorkArea"; this.tbWorkArea.Size <- new System.Drawing.Size (566, 377); this.tbWorkArea.ForeColor <- Color.FromArgb (255, 0, 0, 0); this.tbWorkArea.BackColor <- Color.FromArgb (255, 255, 255, 255); this.tbWorkArea.TabIndex <- 0; this.tbWorkArea.WordWrap <- false; this.tbWorkArea.KeyUp.Add (fun e -> this.tbWorkArea_KeyUp e); // // proc // this.proc.StartInfo.UseShellExecute <- false; this.proc.StartInfo.CreateNoWindow <- true; this.proc.StartInfo.RedirectStandardInput <- true; this.proc.StartInfo.RedirectStandardOutput <- true; this.proc.StartInfo.RedirectStandardError <- true; this.proc.StartInfo.Domain <- ""; this.proc.StartInfo.LoadUserProfile <- false; this.proc.StartInfo.UserName <- ""; this.proc.StartInfo.Password <- null; this.proc.SynchronizingObject <- this; // // msMain // this.msMain.Items.AddRange [| (this.miFile :> System.Windows.Forms.ToolStripItem); (this.miWorkspace :> System.Windows.Forms.ToolStripItem); |]; this.msMain.Location <- new System.Drawing.Point (0, 0); this.msMain.Name <- "msMain"; this.msMain.Size <- new System.Drawing.Size (566, 24); this.msMain.TabIndex <- 1; this.msMain.Text <- "menu"; // // miFile // this.miFile.DropDownItems.AddRange [| (this.miSave :> System.Windows.Forms.ToolStripItem); (this.miOpen :> System.Windows.Forms.ToolStripItem); (this.miExit :> System.Windows.Forms.ToolStripItem) |]; this.miFile.Name <- "miFile"; this.miFile.Size <- new System.Drawing.Size (35, 20); this.miFile.Text <- "&File"; // // miSave // this.miSave.Name <- "miSave"; this.miSave.ShortcutKeys <- Enum.combine [System.Windows.Forms.Keys.Control; System.Windows.Forms.Keys.S]; this.miSave.Size <- new System.Drawing.Size (140, 22); this.miSave.Text <- "&Save"; this.miSave.Click.Add (fun e -> this.miSave_Click e); // // miOpen // this.miOpen.Name <- "miOpen"; this.miOpen.ShortcutKeys <- Enum.combine [System.Windows.Forms.Keys.Control; System.Windows.Forms.Keys.O]; this.miOpen.Size <- new System.Drawing.Size (140, 22); this.miOpen.Text <- "&Open"; this.miOpen.Click.Add (fun e -> this.miOpen_Click e); // // miExit // this.miExit.Name <- "miExit"; this.miExit.Size <- new System.Drawing.Size (140, 22); this.miExit.Text <- "E&xit"; this.miExit.Click.Add (fun e -> this.miExit_Click e); // // miWorkspace // this.miWorkspace.DropDownItems.AddRange [| (this.miFont :> System.Windows.Forms.ToolStripItem); (this.miTextColor :> System.Windows.Forms.ToolStripItem); (this.miBackColor :> System.Windows.Forms.ToolStripItem); |]; this.miWorkspace.Name <- "miWorkspace"; this.miWorkspace.Size <- new System.Drawing.Size (72, 20); this.miWorkspace.Text <- "&Workspace"; // // miFont // this.miFont.Name <- "miFont"; this.miFont.Size <- new System.Drawing.Size (158, 22); this.miFont.Text <- "F&ont"; this.miFont.Click.Add (fun e -> this.miFont_Click e); // // miTextColor // this.miTextColor.Name <- "miTextColor"; this.miTextColor.Size <- new System.Drawing.Size (158, 22); this.miTextColor.Text <- "&Text Color"; this.miTextColor.Click.Add (fun e -> this.miTextColor_Click e); // // miBackColor // this.miBackColor.Name <- "miBackColor"; this.miBackColor.Size <- new System.Drawing.Size (158, 22); this.miBackColor.Text <- "&Background Color"; this.miBackColor.Click.Add (fun e -> this.miBackColor_Click e); // // sfdSave // this.sfdSave.Filter <- ml_pattern_filter; this.sfdSave.CheckFileExists <- true; this.sfdSave.FileOk.Add (fun e -> this.sfdSave_FileOk e); // // ofdOpen // // this.ofdOpen.FileName <- "openFileDialog1"; this.ofdOpen.Filter <- ml_pattern_filter; this.ofdOpen.FileOk.Add (fun e -> this.ofdOpen_FileOk e); // // MainForm // this.AutoScaleDimensions <- new System.Drawing.SizeF (Convert.ToSingle 6, Convert.ToSingle 13); this.AutoScaleMode <- System.Windows.Forms.AutoScaleMode.Font; this.ClientSize <- new System.Drawing.Size (566, 401); this.Controls.Add this.tbWorkArea; this.Controls.Add this.msMain; this.MainMenuStrip <- this.msMain; this.Name <- "MainForm"; this.Text <- "OCaml"; this.FormClosing.Add (fun e -> this.MainForm_FormClosing e); this.msMain.ResumeLayout false; this.msMain.PerformLayout (); this.ResumeLayout false; this.PerformLayout () member this.miOpen_Click (e:EventArgs) = this.ofdOpen.ShowDialog () |> ignore member this.miSave_Click (e : EventArgs) = this.sfdSave.ShowDialog () |> ignore member this.miExit_Click (e:EventArgs) = this.Close () member this.miFont_Click (e:EventArgs) = if this.fdFont.ShowDialog () = DialogResult.OK then this.tbWorkArea.Font <- this.fdFont.Font member this.miTextColor_Click (e:EventArgs) = if this.cdColor.ShowDialog () = DialogResult.OK then this.tbWorkArea.ForeColor <- this.cdColor.Color member this.miBackColor_Click (e:EventArgs) = if this.cdColor.ShowDialog () = DialogResult.OK then this.tbWorkArea.BackColor <- this.cdColor.Color member this.ofdOpen_FileOk (e:CancelEventArgs) = using (new StreamReader (this.ofdOpen.FileName)) (fun sr -> let cod = sr.ReadToEnd () in sr.Close (); this.tbWorkArea.AppendText cod) member this.sfdSave_FileOk (e:CancelEventArgs) = using (new StreamWriter (this.sfdSave.FileName)) (fun sw -> sw.Write this.tbWorkArea.Text; sw.Close ()) member this.MainForm_FormClosing (e:FormClosingEventArgs) = this.DoOnClose () member this.tbWorkArea_KeyUp (e : KeyEventArgs) = if e.KeyData = Keys.Enter then begin let text = if this.bookmark >= this.tbWorkArea.Text.Length then begin this.bookmark <- this.tbWorkArea.Text.Length; "" end else if this.tbWorkArea.SelectionLength > 0 then begin this.bookmark <- this.tbWorkArea.Text.Length; this.tbWorkArea.SelectedText end else this.tbWorkArea.Text.Substring this.bookmark in this.proc.StandardInput.Write text end member this.Process_Exited (e : EventArgs) = this.Close () member this.DoOnStart () = this.proc.StartInfo.FileName <- "ocaml"; this.proc.StartInfo.Arguments <- ""; this.proc.Exited.Add (fun e -> this.Process_Exited e); this.proc.EnableRaisingEvents <- true; this.proc.Start () |> ignore; this.stopSignal <- new ManualResetEvent false; this.stdoutReader <- new Thread (this.DoReadFrom this.proc.StandardOutput); this.stderrReader <- new Thread (this.DoReadFrom this.proc.StandardError); this.stdoutReader.Start (); this.stderrReader.Start () member this.DoOnClose () = this.stopSignal.Set () |> ignore; (fun () -> this.proc.StandardError.Close ()) |> swallow; (fun () -> this.proc.StandardInput.Close ()) |> swallow; (fun () -> this.proc.StandardOutput.Close ()) |> swallow; (fun () -> if not (this.proc.WaitForExit 200) then this.proc.Kill (); this.proc.Close ()) |> swallow; (fun () -> if not (this.stdoutReader.Join 100) then this.stdoutReader.Abort ()) |> swallow; (fun () -> if not (this.stderrReader.Join 100) then this.stderrReader.Abort ()) |> swallow; member this.DoReadFrom (reader : System.IO.StreamReader) : ThreadStart = let MAX_BUF = 4096 in new ThreadStart (fun () -> let lbuffer = Array.zero_create MAX_BUF in let mutable bread = 0 in try while true do bread <- reader.Read (lbuffer, 0, MAX_BUF); while bread > 0 do this.AppendText (new string (lbuffer, 0, bread)); bread <- reader.Read (lbuffer, 0, MAX_BUF) done; if this.stopSignal.WaitOne (10, true) then raise Exit done with _ -> ()) member this.AppendText text = if this.tbWorkArea.InvokeRequired then let del = new Converter<_,_> (fun t -> this.AppendText t) in this.Invoke (del, [| box text |]) |> ignore else begin this.tbWorkArea.AppendText text; this.bookmark <- this.tbWorkArea.Text.Length end end [<STAThread>] let main () = Application.EnableVisualStyles (); Application.SetCompatibleTextRenderingDefault false; Thread.Sleep 400; Application.Run (new MainForm ()) [<STAThread>] do main ()
Thankyou very much!
Topic tags
- f# × 3705
- websharper × 1897
- compiler × 286
- functional × 201
- ui next × 139
- c# × 121
- classes × 97
- web × 97
- .net × 84
- book × 84
- async × 76
- ui.next × 67
- bug × 54
- core × 49
- website × 49
- server × 45
- parallel × 43
- ui × 43
- enhancement × 41
- parsing × 41
- testing × 41
- trywebsharper × 41
- typescript × 37
- html × 35
- javascript × 35
- owin × 35
- asynchronous × 30
- monad × 28
- ocaml × 28
- tutorial × 27
- warp × 27
- haskell × 26
- sitelet × 25
- linq × 22
- workflows × 22
- wpf × 20
- fpish × 19
- introduction × 19
- silverlight × 19
- sitelets × 19
- monodevelop × 17
- rpc × 17
- suave × 17
- piglets × 16
- collections × 15
- feature request × 15
- jquery × 15
- templates × 15
- getting started × 14
- pipeline × 14
- kendoui × 13
- reactive × 12
- 4.1.0.171 × 11
- monads × 11
- opinion × 10
- 4.0.190.100-rc × 9
- deployment × 9
- fixed × 9
- formlets × 9
- in × 9
- json × 9
- plugin × 9
- proposal × 9
- scheme × 9
- solid × 9
- basics × 8
- concurrent × 8
- highcharts × 8
- how-to × 8
- python × 8
- 4.1.1.175 × 7
- complexity × 7
- documentation × 7
- visual studio × 7
- 4.1.2.178 × 6
- lisp × 6
- real-world × 6
- released in 4.0.192.103-rc × 6
- remoting × 6
- resources × 6
- scala × 6
- websharper ui.next × 6
- workshop × 6
- xaml × 6
- 4.0.193.110 × 5
- 4.2.3.236 × 5
- aspnetmvc × 5
- authentication × 5
- azure × 5
- bootstrap × 5
- conference × 5
- dsl × 5
- formlet × 5
- java × 5
- list × 5
- metaprogramming × 5
- ml × 5
- released in Zafir.4.0.188.91-beta10 × 5
- sql × 5
- visualstudio × 5
- websharper.forms × 5
- zafir × 5
- 4.0.192.106 × 4
- 4.0.195.127 × 4
- 4.1.0.38 × 4
- 4.2.1.86 × 4
- 4.2.6.118 × 4
- css × 4
- example × 4
- extensions × 4
- fsi × 4
- fsx × 4
- html5 × 4
- jqueryui × 4
- lift × 4
- reflection × 4
- remote × 4
- rest × 4
- spa × 4
- teaching × 4
- template × 4
- websocket × 4
- wontfix × 4
- 4.0.196.147 × 3
- 4.1.0.34 × 3
- 4.1.6.207 × 3
- 4.2.1.223-beta × 3
- 4.2.11.258 × 3
- 4.2.4.114 × 3
- 4.2.4.247 × 3
- 4.2.5.115 × 3
- 4.2.6.253 × 3
- 4.2.9.256 × 3
- ajax × 3
- alt.net × 3
- aml × 3
- asp.net mvc × 3
- canvas × 3
- cloudsharper × 3
- compilation × 3
- database × 3
- erlang × 3
- events × 3
- extension × 3
- file upload × 3
- forums × 3
- inline × 3
- issue × 3
- kendo × 3
- macro × 3
- mono × 3
- msbuild × 3
- mvc × 3
- pattern × 3
- piglet × 3
- released in Zafir.4.0.187.90-beta10 × 3
- svg × 3
- type provider × 3
- view × 3
- 4.1.1.64 × 2
- 4.1.5.203 × 2
- 4.1.7.232 × 2
- 4.2.10.257 × 2
- 4.2.3.111 × 2
- 4.2.5.249 × 2
- android × 2
- asp.net × 2
- beginner × 2
- blog × 2
- chart × 2
- client × 2
- client server app × 2
- clojure × 2
- computation expressions × 2
- constructor × 2
- corporate × 2
- courses × 2
- cufp × 2
- d3 × 2
- debugging × 2
- direct × 2
- discriminated union × 2
- docs × 2
- elm × 2
- endpoint × 2
- endpoints × 2
- enterprise × 2
- entity framework × 2
- event × 2
- f# interactive × 2
- fable × 2
- flowlet × 2
- formdata × 2
- forms × 2
- fsc × 2
- google maps × 2
- hosting × 2
- http × 2
- https × 2
- iis 8.0 × 2
- install × 2
- interactive × 2
- interface × 2
- iphone × 2
- iteratee × 2
- jobs × 2
- jquery mobile × 2
- keynote × 2
- lens × 2
- lenses × 2
- linux × 2
- listmodel × 2
- mac × 2
- numeric × 2
- oauth × 2
- obfuscation × 2
- offline × 2
- oop × 2
- osx × 2
- packaging × 2
- pattern matching × 2
- performance × 2
- pipelines × 2
- q&a × 2
- quotation × 2
- reference × 2
- released in Zafir.4.0.185.88-beta10 × 2
- rx × 2
- script × 2
- security × 2
- self host × 2
- seq × 2
- sockets × 2
- stm × 2
- tcp × 2
- trie × 2
- tutorials × 2
- type × 2
- url × 2
- var × 2
- websharper.charting × 2
- websharper4 × 2
- websockets × 2
- wig × 2
- xna × 2
- zh × 2
- .net interop × 1
- 2012 × 1
- 4.0.194.126 × 1
- 4.1.3.184 × 1
- 4.1.4.189 × 1
- 4.2.0.214-beta × 1
- 4.2.12.259 × 1
- 4.2.2.231-beta × 1
- 4.2.8.255 × 1
- Canvas Sample Example × 1
- DynamicStyle Animated Style × 1
- Fixed in 4.0.190.100-rc × 1
- Released in Zafir.UI.Next.4.0.169.79-beta10 × 1
- SvgDynamicAttribute × 1
- WebComponent × 1
- abstract class × 1
- accumulator × 1
- active pattern × 1
- actor × 1
- addin × 1
- agents × 1
- aggregation × 1
- agile × 1
- alter session × 1
- animation × 1
- anonymous object × 1
- apache × 1
- api × 1
- appcelerator × 1
- architecture × 1
- array × 1
- arrays × 1
- asp.net 4.5 × 1
- asp.net core × 1
- asp.net integration × 1
- asp.net mvc 4 × 1
- asp.net web api × 1
- aspnet × 1
- ast × 1
- attributes × 1
- authorization × 1
- b-tree × 1
- back button × 1
- badimageformatexception × 1
- bash script × 1
- batching × 1
- binding-vars × 1
- bistro × 1
- body × 1
- bundle × 1
- camtasia studio × 1
- cas protocol × 1
- charts × 1
- clarity × 1
- class × 1
- cli × 1
- clipboard × 1
- clojurescript × 1
- closures × 1
- cloud × 1
- cms × 1
- coding diacritics × 1
- color highlighting × 1
- color zones × 1
- combinator × 1
- combinators × 1
- compile × 1
- compile code on server × 1
- config × 1
- confirm × 1
- content × 1
- context × 1
- context.usersession × 1
- continuation-passing style × 1
- coords × 1
- cordova × 1
- cors × 1
- coursera × 1
- cross-domain × 1
- csla × 1
- current_schema × 1
- custom content × 1
- data × 1
- data grid × 1
- datetime × 1
- debug × 1
- declarative × 1
- delete × 1
- devexpress × 1
- dhtmlx × 1
- dictionary × 1
- directattribute × 1
- disqus × 1
- distance × 1
- do binding × 1
- doc elt ui.next upgrade × 1
- docker × 1
- dojo × 1
- dol × 1
- dom × 1
- domain × 1
- du × 1
- duf-101 × 1
- dynamic × 1
- eastern language × 1
- eclipse × 1
- edsl × 1
- em algorithm × 1
- emacs × 1
- emotion × 1
- enums × 1
- error × 1
- etw × 1
- euclidean × 1
- eventhandlerlist × 1
- examples × 1
- ext js × 1
- extension methods × 1
- extra × 1
- facet pattern × 1
- failed to translate × 1
- fake × 1
- fantomas × 1
- fear × 1
- float × 1
- form × 1
- form-data × 1
- forum × 1
- fp × 1
- frank × 1
- fsdoc × 1
- fsharp × 1
- fsharp.core × 1
- fsharp.powerpack × 1
- fsharpx × 1
- fsunit × 1
- function × 1
- functional style × 1
- game × 1
- games × 1
- gc × 1
- generic × 1
- geometry × 1
- getlastwin32error × 1
- getting-started × 1
- google × 1
- google.maps × 1
- grid × 1
- group × 1
- guide × 1
- hash × 1
- headers × 1
- hello world example × 1
- heroku × 1
- highchart × 1
- history × 1
- how to × 1
- html-templating × 1
- http405 × 1
- httpcontext × 1
- hubfs × 1
- i18n × 1
- ie 8 × 1
- if-doc × 1
- iis × 1
- image × 1
- images × 1
- inheritance × 1
- initialize × 1
- input × 1
- install "visual studio" × 1
- installer × 1
- int64 × 1
- interfaces × 1
- internet explorer × 1
- interop × 1
- interpreter × 1
- io × 1
- iobservable × 1
- ios × 1
- iot × 1
- ipad × 1
- isomorphic × 1
- javascript optimization × 1
- javascript semanticui resources × 1
- jquery-plugin × 1
- jquery-ui × 1
- jquery-ui-datepicker × 1
- js × 1
- kendo datasource × 1
- kendochart × 1
- kendoui compiler × 1
- knockout × 1
- l10n × 1
- learning × 1
- library × 1
- libs × 1
- license × 1
- licensing × 1
- lineserieszonescfg × 1
- local setting × 1
- localization × 1
- logging × 1
- loop × 1
- macros × 1
- mailboxprocessor × 1
- mapping × 1
- maps × 1
- markerclusterer × 1
- markup × 1
- marshal × 1
- math × 1
- mathjax × 1
- message × 1
- message passing × 1
- message-passing × 1
- meta × 1
- metro style × 1
- micro orm × 1
- minimum-requirements × 1
- mix × 1
- mobile installation × 1
- mod_mono × 1
- modal × 1
- module × 1
- mouseevent × 1
- mouseposition × 1
- multidimensional × 1
- multiline × 1
- multithreading × 1
- mysql × 1
- mysqlclient × 1
- nancy × 1
- native × 1
- nested × 1
- nested loops × 1
- node × 1
- nunit × 1
- object relation mapper × 1
- object-oriented × 1
- om × 1
- onboarding × 1
- onclick × 1
- optimization × 1
- option × 1
- orm × 1
- os x × 1
- output-path × 1
- override × 1
- paper × 1
- parameter × 1
- persistence × 1
- persistent data structure × 1
- phonegap × 1
- pola × 1
- post × 1
- powerpack × 1
- prefix tree × 1
- principle of least authority × 1
- privacy × 1
- private × 1
- profile × 1
- programming × 1
- project × 1
- project euler × 1
- projekt_feladat × 1
- protected × 1
- provider × 1
- proxy × 1
- ptvs × 1
- public × 1
- pure f# × 1
- purescript × 1
- qna × 1
- quant × 1
- query sitelet × 1
- question × 1
- quotations × 1
- range × 1
- raphael × 1
- razor × 1
- rc × 1
- reactjs × 1
- real-time × 1
- ref × 1
- region × 1
- released in 4.0.190.100-rc × 1
- reporting × 1
- responsive design × 1
- rest api × 1
- rest sitelet × 1
- restful × 1
- round table × 1
- router × 1
- routing × 1
- rpc reverseproxy × 1
- runtime × 1
- sales × 1
- sample × 1
- sampleapp × 1
- scriptcs × 1
- scripting × 1
- search × 1
- self hosted × 1
- semanticui × 1
- sequence × 1
- serialisation × 1
- service × 1
- session-state × 1
- sharepoint × 1
- signals × 1
- sitelet website × 1
- sitelet.protect × 1
- sitlets × 1
- slickgrid × 1
- source code × 1
- sqlentityconnection × 1
- ssl × 1
- standards × 1
- static content × 1
- stickynotes × 1
- streamreader × 1
- stress × 1
- strong name × 1
- structures × 1
- submitbutton × 1
- subscribe × 1
- svg example html5 websharper.ui.next × 1
- sweetalert × 1
- system.datetime × 1
- system.reflection.targetinvocationexception × 1
- table storage × 1
- targets × 1
- tdd × 1
- templates ui.next × 1
- templating × 1
- text parsing × 1
- three.js × 1
- time travel × 1
- tls × 1
- tooltip × 1
- tracing × 1
- tsunamiide × 1
- turkish × 1
- twitter-bootstrap × 1
- type erasure × 1
- type inference × 1
- type providers × 1
- type-providers × 1
- typeprovider × 1
- ui next forms × 1
- ui-next × 1
- ui.next jqueryui × 1
- ui.next charting × 1
- ui.next formlets × 1
- ui.next forms × 1
- ui.next suave visualstudio × 1
- ui.next templating × 1
- unicode × 1
- unittest client × 1
- upload × 1
- usersession × 1
- validation × 1
- vb × 1
- vb.net × 1
- vector × 1
- view.map × 1
- visal studio × 1
- visual f# × 1
- visual studio 11 × 1
- visual studio 2012 × 1
- visual studio shell × 1
- vs2017 compiler zafir × 1
- vsix × 1
- web api × 1
- web-scraping × 1
- webapi × 1
- webcomponents × 1
- webforms × 1
- webgl × 1
- webrtc × 1
- webshaper × 1
- websharper async × 1
- websharper codemirror × 1
- websharper f# google × 1
- websharper forms × 1
- websharper reactive × 1
- websharper rpc × 1
- websharper sitelets routing × 1
- websharper warp × 1
- websharper-interface-generator × 1
- websharper.chartsjs × 1
- websharper.com × 1
- websharper.exe × 1
- websharper.owin × 1
- websharper.ui.next × 1
- websharper.ui.next jquery × 1
- websockets iis × 1
- why-websharper × 1
- windows 7 × 1
- windows 8 × 1
- windows-phone × 1
- winrt × 1
- www.grabbitmedia.com × 1
- xamarin × 1
- xml × 1
- yeoman × 1
- yield × 1
- zafir beta × 1
- zafir websharper4 × 1
- zarovizsga × 1
![]() |
Copyright (c) 2011-2012 IntelliFactory. All rights reserved. Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy |
Built with WebSharper |
This was one of my first attempts to write codes in F#. Ofcource It is not a perfect sample, but It is still useful. The console application that will be run is 'ocaml'. You can replace it with any other applications that you want. I wrote it when I was trying to learn ocaml and I wanted to save my sessions. Take a look and let me know ( and learn ) if there is any issues.Thanks.