Attachment 'wpfXamlDemo.v1.6.txt'
Download 1 :Namespace wpfXamlDemo
2
3 ⍝ === VARIABLES ===
4
5 L←⎕av[3+⎕io]
6
7 Copy_b64 ←'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAaVBMVEX///8AAAC2tra2tra2tra2trb////+/v62trb9/f309PT7+/vExMSurq6Hh4f4+Pj8/Pz5+fnMzMyenp6/zduoqKilpaXNzc2xsbHu7u6Li4vk5OTa2tro6Oj6+vrm5uaMjIympqby8vJPA9lJAAAABnRSTlMAAM8Q7zCjkYU+AAAAiklEQVR4XoXM2Q7CMAxE0bqAk+7s+/7/H4mJMGNXQdzXo5mCiKK2X01nlCpSkbXdspxk4VCLOHBvDvwbYPSWgxu/JQMn5rotMzA8L+d24wAFB+tvzEeFIGDr/0LlrjwEE2D+CxoZ4aoCLASQgau8mQAsb7hqFLp7L28mBSKKPJgS0AdcgO6xtQm8AN3LEZUq6MiXAAAAAElFTkSuQmCC'
8 Cut_b64 ←'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADcElEQVRIiZ2VX2gcVRjFz52d3TYmWW+6q02y1m4bEPOiE6T+K8gWNArFtqB9EIRuUBGKsEbR1zYoiL5UH6uYrAF9KGpWTFFEmLRapW2M26ZNuq3JbksLppvsbqY7O3dm7p3xoV1N3K6Z8Xu6zJzv/L4z93IHruvCdV14rQ9GvqPvfZzJr6Wr+8qenW+VLAdV1+Fxz3pCiGfz9NHTBzva71CuF4veB/KsBLAuFExt3bQRpcXF274/MjFDHQcqce3nAcwBgOTVvKTbcTkg0c5IGIFAY+qvjs9SQqA6rquYptlWf+4ZsKE1WJAlgqBMIEurAeO/5GhAIurGjrBCHBvasjbnGwAAcoAgJEurEnx/6hKVCFE7I2Eleud6LBaL06+98GT1/wMC/yRQp/6gsgS1M9qu9G6+CzMX8zBqtfdX9fgBAAAhBCDAj5OXKEDUrmi70hOL4ufJWVy99mf67Zd3f75S7yuBLVxY3IELCVxAjdJW5f5778apbA7nc/Nfvp58duDfPb4AXLjQGUcbjSJC25StsSiOn57BuVw+nUru2nu7Hl8AZtoYV09C16vY0h3BT5OzOHthPr3/xZ0Nk/sGbNs/lVgoLiEoy1haKuHEb7OYvpBPp/Y1fpaV1bDJA99YCUc4KXaDUWPZOKaX9AzT2CFTNxNciqDGqgiG1mPu8rXMWy/t+k/zBsDe4VLS0IwRhztZUzepqZsJbvID3OYQtqh8rfL0A0907bmSPR+/OL1wzEtyqX6t9r+bp7Vy7ZBe0gePDHT0GctGH9MYrJoFYYosgC2/fvL4oBXePCR19QLAbk+A+oJVWVIv65VvU90fAoC2oFFWZbANO+sIZ8fvww9XAEBwMRFsaUEgFFJ6+g/v8Q7QGDXKBgDgoVcmqc3sMbtmZwUXO6Y+3Vap60afaymsaw2j95mnaezBvrH7dg7ne/oPx9cEWDWrYOpmXEmezHOL521mQ9ji78lXFrc4AKkS7o4Nhbs3UQAH1gRk04+kucXT3OQFYYmPzo4+1ndm9NEG8zrAEc7A+GDsoOtiEECiGWDVKTr3xfY1jx0AcJPj6Jv3ZADAFW4BAG2agBACP79N4GaCp96Zj9+EsX0AJpoCfDnfKmGJAjf52PY3zowwrZwE8Fkzre/rGgC4xYfMG9pI+XJOERYbmvvh1Uwz7V8tIZ5QE98wygAAAABJRU5ErkJggg=='
9 HandCursor_b64 ←'AAACAAEAICAAAAgAAACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH8AAP//AAD//wAA/38AAP9/AAD/fwAA/38AAP9/AAD/fwAA/38AAP8AAAD/gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAfwAA//8AAP//AAD/fwAA/38AAP9/AAD/fwAA/38AAP9/AAD/fwAA/wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAAB/AAD//wAA//8AAP9/AAD/fwAA/38AAP9/AAD/fwAA/38AAP9/AAD/AAAA/4CAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH8AAP//AAD//wAA/38AAP9/AAD/fwAA/38AAP9/AAD/fwAA/38AAP8AAAD/gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAfwAA//8AAP//AAD/fwAA/38AAP9/AAD/fwAA/38AAP9/AAD/fwAA/wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAfwAA/38AAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAAB/f3//nM7//5zO//+czv//nM7//5zO//+czv//v7+//wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//nM7//5zO//+czv//nM7//5zO//+/v7//AAAA/4CAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAAB/f3//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+/v7//AAAA/4CAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAf39//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//7+/v/8AAAD/gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//7+/v/8AAAD/gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAf39//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//v7+//wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+/v7//AAAA/4CAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAf39//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+/v7//AAAA/4CAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//7+/v/8AAAD/gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAf39//5zO//+czv//v7+//7+/v/+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//v7+//wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//nM7//7+/v/8AAAD/AAAA/5zO//+czv//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//+/v7//AAAA/4CAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAf39//5zO//+/v7//AAAA/4CAAAB/f3//nM7//5zO//+czv//nM7//5zO//+czv//nM7//5zO//9/f3//nM7//7+/v/8AAAD/gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//v7+//wAAAP+AgAAAgIAAAH9/f/+czv//nM7//39/f/+czv//nM7//39/f/+czv//v7+//wAAAP+czv//v7+//wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAf39//39/f/8AAAD/gIAAAICAAACAgAAAf39//5zO//+/v7//AAAA/5zO//+/v7//AAAA/5zO//+/v7//AAAA/5zO//+/v7//AAAA/4CAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAAB/f3//nM7//7+/v/8AAAD/nM7//7+/v/8AAAD/nM7//7+/v/8AAAD/f39//39/f/+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//v7+//wAAAP+czv//v7+//wAAAP+czv//v7+//wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAf39//5zO//+/v7//AAAA/5zO//+/v7//AAAA/39/f/9/f3//gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAAB/f3//nM7//7+/v/8AAAD/f39//39/f/+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//v7+//wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAf39//5zO//+/v7//AAAA/4CAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAAB/f3//nM7//7+/v/8AAAD/gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/+czv//v7+//wAAAP+AgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAH9/f/9/f3//gIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAAgIAAAICAAACAgAAA///////////+AD///gA///4AP//+AD///gA///8Af///AH///wB///4AP//8AD//+AAf//gAH//wAB//8AAP/+AAD//gAA//wAAP/8IAD/+GAA//jgAP//4AH//+AH///gD///4H///+H////h////4f///+H////z////////8='
10 Paste_b64 ←'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAeFBMVEUAAAB7e3ucnJy1tbXOpUrOpVLOrVrnzpz39/f////OrWPn5+fOzs7WtWvWvXuEhITnzqXn1qWUlJRaWlq1nGO9zt6MjIyle0KlhDmljFqlpaXWrWOthEKtlFrW1tbexoTnzpS1hDG1lGOUc0KMYxjv7++9vb3GrXO+vRrUAAAAAXRSTlMAQObYZgAAAKNJREFUeF6NzVcOwyAQRVHTi3tL73X/OwzjeISxiZT7hXT0huRbCSVhV4hQSskDXhOo66pqCSFtp5QK4FwUDXTIiwCqPLfv7nbcbqScgXUxjDKGYAcwY2kGEgGdGZAlmJMGQZAeUpa9EKR04HumuwGkC6DHjFkBKADhYFI5ghBREFBwygPnkcVlz3kchiKn1ndoscCY0b4Z9Jj+a/H7j6aclnwANmEWNaPqN4UAAAAASUVORK5CYII='
11 Print_b64 ←'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAEUUlEQVR4nN2UTWwUZRzGf/O+szPUlo8tRaGK3aQpmJZ+kTSGSEQ4GBCacOSi1AMHExPxYuJJTkajBxKPHkQ9eDKp0QQMdNMaE+SirXyUFmt2+6Ww3ZbZmd2d2feddzy0NqWCARIv/pM5TZ7n9/94ZuA/LutRBTcnJt/z/eCMMeac4ziDtm2Pdu5pz98Yn+iO43iLlAIhxOhzu3d5APZjNDVgjEEIMSClGLBtyeSt31ZeJcRxzNTU7xnAAxCP4vzr1esntdYZHcdYloVlWQghkNJGSokQAmPMYP+xV/J/ax5pgiAIBoQQkCQkK48xhjiOqdUijDHkcvnBtZqHvsH57y8ekFIOC0vgOClc1yWVSiGlJAxDlFLUauruoYMvptfqHmqCoexw9+07hQHHcZBSYtsS13URlkBrjUkMwhL4vn9uvfaBgKHscDdwGjgehuGWDa5LoVBgQ10dxhgcx0EIC8sSFO7cJt24FaVqZ9f7WOtMW4ABYKCmVCbwfRaXllBKUy6XKRYXqK+vx3VckiTBcV20VuzYvp1dbW3s3PkM1TDM+X4w3NvT9foqYHpm9q0oil6anp45Xir5eJ6HHwT3dBLHMeM3rmOMASBJEjKZDL29PfR0dxMEZcIopFypUiwu0n/0sLW6oiiKzm7etJGRkRGU0gghwFoezsTxKkQIidaK9vYO9u9/gaebmyn5PjOzcyilCIIyUa222sQqQGtNYaHIxMQEQghs2yaVSuE4y0lJpVIYY9i373n6+vpobGzEdR0Wi0t4XomS76OUwsSGxBiSJFkHUMtJmJuZftDNcRyHkydfxXUcUvZyNmqqhtYarRSxjjHGoNdMvApQSmESw+LCwn3NTRyDZXHh8nn2tu6lo70D25aoWg2tFErrFUBMHMdYQt4LiKIQkyREYfgP8w1aYycJSgqKO4vMl+dpDVuxpSSMIqIoQkU1dKxXvmpDKgWtLZk0ULMBqtUqxhha29qYyecRlQpNlQrpsIoWgtC28R2XzmIXT21/kkq5jLQl1UqFMAwJw5A4Xl7R3Nys9+MPI++u9FexAcrlytk41qe7enp5OdNMd2GYoaFFclVIgG2WRbHuCWZnZ3CcFA319UgpCYKAcjmgUikThqEeG/1ldCSbPQNcmMrn4tUV9fcfffvLDz+oO9VcOtXWOSjCux5dNyE/Ad8C15KEhqatWEDJ8/A2bkRKQcnz8P2AW5OTxeylix+XPO+TqXyufM+RkyQ5UK1W36n76I1XqB+E3R51P0OdDZtZ/p8fAuqbmriyaRMAxeICUgjm//hTDWez390cH39zKp+bv19ALIDWlow8fORI59Fjx17ryF3e/+ztq32c+wYzC5UE1IkTd97f0XxpbGxs85Z0utd1nMD3S6PXrl77dCqfu3Tf6K0FrK3WlkxLx549vae6uw62NzS0j6fT17++/NNXn33x+ZV/M3powBpQGtgGFKbyuaXHMf9/1F8Bcja9IXWf7wAAAABJRU5ErkJggg=='
12 Quit_b64 ←'iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHUSURBVEiJzZWxaxNhGMZ/z7VEQXBzbpYsDi5myx/g1II4FAwmNoMQOknXom2nDu7SxdxpjEPIH9CtOCd7ix3q3E2wbSr0dbjXWs19l5xa8IGDg+d9nh/fdx/fycy4TkVFhhPpWSy1rg1g8Bho/FNALN38E286QFIi1SPYzwnvJ1IdSYUAe9J8AgOga3AQCrvXTWCwJ83PBOhLc0fQBZaAVtPsQQjgXgtYOoJuX5qbCjiFFcGyYLVp1gmVX4F0BKuC5VNYyQX0pRKwbrDbMNuZVv5DDbMdg11g3TuyASewaLAAbM9afkXbBgsnsBgEAPeAs8/wsWi7Z868Iwi4Cxy+NLsI9LwV9LIMzxx6x6V+P1rfgBIBPTV7E/JcJe+41C8rEAyBynvp9pSiCXmm4h3ZAEtNnUO1KMAzsjxABCPgOIKtTWnmi3BTiiLY8uwoCHhi9hVoA7UyPJ8V4LM1oO0dP2VmE08MvRjGMaxtQJQ1Y2ZsQBTDms/2smYyL6gxtG+kr6/K8LAjvSjBsG72BdIPeg7VcrotNeDDOF35hJT3y0ykR8Br4A5gwCe3KoCAY6DdNBuEOnIBAO+kWxdwX1A1P12CocEwgtHEnhcF/K0K/ZP/S8B30crIq93trIsAAAAASUVORK5CYII='
13 Settings_b64 ←'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'
14
15
16 _←⍬
17 _,←'<Window'
18 _,←L,' xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"'
19 _,←L,' xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">'
20 _,←L,'</Window>'
21 NewWindow←_
22
23 _←⍬
24 _,←'<Window'
25 _,←L,' xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"'
26 _,←L,' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"'
27 _,←L,' xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"'
28 _,←L,' Height="200"'
29 _,←L,' Width="250"'
30 _,←L,' Title="MainWindow"'
31 _,←L,' WindowStartupLocation="CenterScreen">'
32 _,←L,' <Grid>'
33 _,←L,' <Grid.RowDefinitions>'
34 _,←L,' <RowDefinition Height="0.5*"/>'
35 _,←L,' <RowDefinition Height="0.5*"/>'
36 _,←L,' </Grid.RowDefinitions>'
37 _,←L,' <TextBox'
38 _,←L,' x:Name="textBox1"'
39 _,←L,' Width="130"'
40 _,←L,' HorizontalAlignment="Center"'
41 _,←L,' VerticalAlignment="Center"'
42 _,←L,' Text="TextBox"'
43 _,←L,' TextAlignment="Center"/>'
44 _,←L,' <Button'
45 _,←L,' x:Name="button1"'
46 _,←L,' Height="40"'
47 _,←L,' Width="120"'
48 _,←L,' Grid.Row="1"'
49 _,←L,' HorizontalAlignment="Center"'
50 _,←L,' VerticalAlignment="Center"'
51 _,←L,' Content="Click Me !"/>'
52 _,←L,' </Grid>'
53 _,←L,'</Window>'
54 sample1←_
55
56 _←⍬
57 _,←'<Window'
58 _,←L,' xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"'
59 _,←L,' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"'
60 _,←L,' xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"'
61 _,←L,' x:Class="WpfApplication3.MainWindow"'
62 _,←L,' Height="200"'
63 _,←L,' Width="250"'
64 _,←L,' Title="MainWindow"'
65 _,←L,' WindowStartupLocation="CenterScreen">'
66 _,←L,' <Grid>'
67 _,←L,' <Grid.RowDefinitions>'
68 _,←L,' <RowDefinition Height="0.5*"/>'
69 _,←L,' <RowDefinition Height="0.5*"/>'
70 _,←L,' </Grid.RowDefinitions>'
71 _,←L,' <TextBox'
72 _,←L,' x:Name="textBox1"'
73 _,←L,' Width="130"'
74 _,←L,' HorizontalAlignment="Center"'
75 _,←L,' VerticalAlignment="Center"'
76 _,←L,' Text="TextBox"'
77 _,←L,' TextAlignment="Center"/>'
78 _,←L,' <Button'
79 _,←L,' x:Name="button1"'
80 _,←L,' Click="__Button_Click"'
81 _,←L,' Height="40"'
82 _,←L,' Width="120"'
83 _,←L,' Grid.Row="1"'
84 _,←L,' HorizontalAlignment="Center"'
85 _,←L,' VerticalAlignment="Center"'
86 _,←L,' Content="Click Me !"/>'
87 _,←L,' </Grid>'
88 _,←L,'</Window>'
89 sample2←_
90
91 _←⍬
92 _,←'<Window'
93 _,←L,' xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"'
94 _,←L,' xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"'
95 _,←L,' Width="640"'
96 _,←L,' Height="480"'
97 _,←L,' Title="PuttingItAllTogether"'
98 _,←L,' WindowStartupLocation="CenterScreen">'
99 _,←L,' <DockPanel Width="Auto" Height="Auto" LastChildFill="True">'
100 _,←L,' <!--Top Menu Area-->'
101 _,←L,' <Menu'
102 _,←L,' Width="Auto"'
103 _,←L,' Height="20"'
104 _,←L,' Background="#FFA9D1F4"'
105 _,←L,' DockPanel.Dock="Top">'
106 _,←L,' <!-- File Menu -->'
107 _,←L,' <MenuItem Header="_File">'
108 _,←L,' <MenuItem Header="_Cut" Name="mnuCut">'
109 _,←L,' <MenuItem.Icon>'
110 _,←L,' <Image Name="Cut_b64" Width="16" Height="16"/>'
111 _,←L,' </MenuItem.Icon>'
112 _,←L,' </MenuItem>'
113 _,←L,' <MenuItem Header="_Copy" Name="mnuCopy">'
114 _,←L,' <MenuItem.Icon>'
115 _,←L,' <Image Name="Copy_b64" Width="16" Height="16"/>'
116 _,←L,' </MenuItem.Icon>'
117 _,←L,' </MenuItem>'
118 _,←L,' <MenuItem Header="_Paste" Name="mnuPaste">'
119 _,←L,' <MenuItem.Icon>'
120 _,←L,' <Image Name="Paste_b64" Width="16" Height="16"/>'
121 _,←L,' </MenuItem.Icon>'
122 _,←L,' </MenuItem>'
123 _,←L,' <Separator/>'
124 _,←L,' <MenuItem Header="_Print" Name="mnuPrint">'
125 _,←L,' <MenuItem.Icon>'
126 _,←L,' <Image Name="Print_b64" Width="16" Height="16"/>'
127 _,←L,' </MenuItem.Icon>'
128 _,←L,' </MenuItem>'
129 _,←L,' <Separator/>'
130 _,←L,' <MenuItem Header="_Quit" Name="mnuQuit">'
131 _,←L,' <MenuItem.Icon>'
132 _,←L,' <Image Name="Quit_b64" Width="16" Height="16"/>'
133 _,←L,' </MenuItem.Icon>'
134 _,←L,' </MenuItem>'
135 _,←L,' </MenuItem>'
136 _,←L,' <!-- About Menu -->'
137 _,←L,' <MenuItem Header="_Help">'
138 _,←L,' <MenuItem Header="_About" Name="mnuAbout"/>'
139 _,←L,' </MenuItem>'
140 _,←L,' </Menu>'
141 _,←L,' <!--Bottom Status Bar area, declared before middle section, '
142 _,←L,' as I want it to fill entire bottom of Window, '
143 _,←L,' which it wouldn''t if there was a Left docked panel before it -->'
144 _,←L,' <StackPanel'
145 _,←L,' Width="Auto"'
146 _,←L,' Height="31"'
147 _,←L,' Background="#FFCAC5C5"'
148 _,←L,' DockPanel.Dock="Bottom"'
149 _,←L,' Orientation="Horizontal">'
150 _,←L,' <Label'
151 _,←L,' Name="lStatusBar"'
152 _,←L,' Width="200"'
153 _,←L,' Height="23"'
154 _,←L,' Content="Status Bar Message...."'
155 _,←L,' FontFamily="Arial"'
156 _,←L,' FontSize="12"/>'
157 _,←L,' </StackPanel>'
158 _,←L,' <!--Left Main Content area-->'
159 _,←L,' <StackPanel'
160 _,←L,' Name="buttonPanel"'
161 _,←L,' Width="136"'
162 _,←L,' Height="Auto"'
163 _,←L,' Background="White">'
164 _,←L,' <Button'
165 _,←L,' Name="btnButton1"'
166 _,←L,' Width="Auto"'
167 _,←L,' Height="26"'
168 _,←L,' Margin="5,5,5,5">'
169 _,←L,' <WrapPanel>'
170 _,←L,' <Image Name="Settings_b64" Height="16" Width="16"/>'
171 _,←L,' <TextBlock Text="Button1" Margin="5,0,0,0"/>'
172 _,←L,' </WrapPanel>'
173 _,←L,' </Button>'
174 _,←L,' <Button'
175 _,←L,' Name="btnButton2"'
176 _,←L,' Width="126"'
177 _,←L,' Height="26"'
178 _,←L,' Margin="5,5,5,5"'
179 _,←L,' Content="Button2"/>'
180 _,←L,' <Button'
181 _,←L,' Name="btnButton3"'
182 _,←L,' Width="126"'
183 _,←L,' Height="26"'
184 _,←L,' Margin="5,5,5,5"'
185 _,←L,' Content="Button3"/>'
186 _,←L,' </StackPanel>'
187 _,←L,' <!--Right Main Content area, NOTE HOW this Grid is the last child'
188 _,←L,' so takes all the remaining room -->'
189 _,←L,' <Grid Width="Auto" Height="Auto" Background="#FFCC9393">'
190 _,←L,' <Grid.ColumnDefinitions>'
191 _,←L,' <ColumnDefinition Width="*"/>'
192 _,←L,' <ColumnDefinition Width="*"/>'
193 _,←L,' </Grid.ColumnDefinitions>'
194 _,←L,' <Grid.RowDefinitions>'
195 _,←L,' <RowDefinition Height="*"/>'
196 _,←L,' <RowDefinition Height="*"/>'
197 _,←L,' </Grid.RowDefinitions>'
198 _,←L,' <Rectangle'
199 _,←L,' Grid.Column="0"'
200 _,←L,' Grid.Row="0"'
201 _,←L,' Margin="10,10,10,10"'
202 _,←L,' Fill="Aqua"/>'
203 _,←L,' <Rectangle'
204 _,←L,' Grid.Column="1"'
205 _,←L,' Grid.Row="0"'
206 _,←L,' Margin="10,10,10,10"'
207 _,←L,' Fill="Aqua"/>'
208 _,←L,' <Rectangle'
209 _,←L,' Grid.Column="0"'
210 _,←L,' Grid.Row="1"'
211 _,←L,' Margin="10,10,10,10"'
212 _,←L,' Fill="Aqua"/>'
213 _,←L,' <Rectangle'
214 _,←L,' Grid.Column="1"'
215 _,←L,' Grid.Row="1"'
216 _,←L,' Margin="10,10,10,10"'
217 _,←L,' Fill="Aqua"/>'
218 _,←L,' </Grid>'
219 _,←L,' </DockPanel>'
220 _,←L,'</Window>'
221 sample3←_
222
223 ⎕ex¨ 'L' '_'
224
225 ⍝ === End of variables definition ===
226
227 (⎕IO ⎕ML ⎕WX)←1 3 3
228
229 ∇ cursor←CursorFromBase64String base64String;imageBytes;MS;⎕USING
230 ⍝ Convert a Base64String to a cursor.
231
232 ⎕USING←'System.IO,mscorlib.dll' 'System,mscorlib.dll' 'System.Windows,WPF/PresentationCore.dll'
233
234 ⍝ Convert Base64 String to byte[]
235 imageBytes←Convert.FromBase64String(⊂base64String)
236
237 ⍝ Create a new MemoryStream with the byte[]
238 MS←⎕NEW MemoryStream(⊂imageBytes)
239
240 ⍝ Create the icon
241 cursor←⎕NEW Input.Cursor MS
242
243 ⍝ Erase the MemoryStream
244 MS.Close ⋄ MS.Dispose ⋄ MS←⎕NULL
245 ∇
246
247 ∇ DemoSample3;imgNames
248
249 ⍝ Parse the xaml of the variable sample3
250 win←FixSimpleXaml sample3
251
252 ⍝ Get the names of all the 'Image' object that has been fixed in rootObj
253 imgNames←{((⊂'Image')≡¨(⍵.⍎¨(⍵.⎕NL-9)).GetType.Name)/(⍵.⎕NL-9)}win
254
255 ⍝ Set the Source of all the 'Image'. Each 'Image' must have a Base64 variable of the same name.
256 win{(⍺.⍎⍵).Source←ImageFromBase64String⍎⍵}¨imgNames
257
258 ⍝ Fix manually the Icon of the main window.
259 win.Icon←ImageFromBase64String Settings_b64
260
261 ⍝ Fix manually the Cursor of the main window.
262 win.Cursor←CursorFromBase64String HandCursor_b64
263
264 ⍝ Set Routed Events on the whole Window for ClickEvent when a MenuItem or a Button are clicked.
265 ⎕USING←'System.Windows,WPF/PresentationCore.dll' 'System.Windows.Controls.Primitives,WPF/PresentationFramework.dll'
266 win.AddHandler(Controls.MenuItem.ClickEvent)(⎕NEW RoutedEventHandler(⎕OR'__EventHandler'))
267 win.AddHandler(ButtonBase.ClickEvent)(⎕NEW RoutedEventHandler(⎕OR'__EventHandler'))
268
269 ⍝ Show the window.
270 win.Show
271 ∇
272
273 ∇ obj DispatchDelegate action;delegate;⎕USING
274 ⍝ Function to write asynchronously to the UI thread from another thread.
275 ⍝ The calling thread does not wait for the operation to finish.
276
277 ⍝ obj = UI Object that you want to write to from another thread
278 ⍝ action = Line to execute in the UI thread. Use '⋄' to write multiple lines.
279
280 :Trap 0
281 ⎕USING←'System,System.dll' 'System.Windows.Threading,WPF/WindowsBase.dll'
282
283 ⍝ Create a function (⍙Delegate) with the 'action' to execute in the UI thread.
284 ⍝ The function will be executed where 'DispatchDelegate' is called and not where
285 ⍝ 'DispatchDelegate' is located.
286 delegate←(⎕IO⊃⎕RSI).⎕OR(⎕IO⊃⎕RSI).⎕FX'⍙Delegate'action'⎕EX ''⍙Delegate'''
287
288 ⍝ Get a 'Dispatcher' from the UI object. That way we are sure to have the right UI thread.
289 ⍝ Use the method '.Invoke' instead of '.BeginInvoke' for synchronous call.
290 {}obj.Dispatcher.BeginInvoke(DispatcherPriority.Normal(⎕NEW Action delegate))
291
292 :Else
293 ⎕←'Error DispatchDelegate: ',action
294
295 ⍝ Returns the Last Error
296 :If 90=⎕EN
297 ⎕←'EXCEPTION: ',⎕EXCEPTION.Message
298 :Else
299 ⎕←(1⊃⎕DM),': ',(2⊃⎕DM)
300 :EndIf
301 :End
302 ∇
303
304 ∇ base64String←FileToBase64String fileName;bytes;⎕USING
305 ⍝ Converts a file to a Base64 String.
306
307 ⎕USING←'System,mscorlib.dll'
308
309 ⍝ Read the file
310 bytes←IO.File.ReadAllBytes(⊂,fileName)
311
312 ⍝ Convert to a Base64 string
313 base64String←Convert.ToBase64String(⊂bytes)
314 ∇
315
316 ∇ rootObj←FixSimpleXaml xamlString;names;⎕USING
317 ⍝ Parse simple and correctly formed Xaml that contains only names to fix (no events).
318 ⍝ Each named element(s) object will be attached to rootObject.
319 ⍝ You can see the list of attached elements by doing rootObject.⎕NL -9
320 ⍝ It is recommended to do not name the root object in the xaml (to prevent a recursive call).
321 ⍝ For 3rd party dll, ⎕USING must be properly initiated before calling this function.
322 ⍝ For Xaml with event callbacks and error trapping see the function: FixXaml.
323 ⍝
324 ⍝ xamlString = Vector of Characters representing a XAML string
325 ⍝ rootObj = WPF Root Element Object if no error
326 ⍝ = ⎕NULL if error
327
328 :Trap 0
329
330 ⍝ Parse the simple Xaml and obtain the root element object:
331 ⎕USING,←⊂'System.Windows.Markup,WPF/PresentationFramework.dll' ⍝ was ⎕USING←' before
332 rootObj←XamlReader.Parse(⊂xamlString)
333
334 ⍝ Extract the names beginning with 'x:Name' or 'Name'
335 names←{{(,⊃0≠⍴¨⍵)/⍵}{1⊃(((⍵[;1]∊⊂'x:Name')∨(⍵[;1]∊⊂'Name'))/⍵[;2]),⊂''}¨(⎕XML ⍵)[;4]}xamlString
336
337 ⍝ Assign the value of each names to the root object:
338 :If 0≠⍴names
339 rootObj{⍎'⍺.',⍵,'←⍺.FindName(⊂,⍵)'}¨names
340 :Else
341 ⍝ Do nothing, there is no names.
342 :End
343
344 :Else
345 ⍝ There is an error.
346 rootObj←⎕NULL
347
348 :EndTrap
349 ∇
350
351 ∇ rootObj←FixXaml xamlString;attribs;caller;data;err;event;events;expr;inter;name;names;ref
352 ⍝ Creates a WPF Object From an APL Character Vector Representing XAML.
353 ⍝ Each named element(s) object will be attached to rootObject.
354 ⍝ You can see the list of attached elements by doing rootObject.⎕NL -9
355 ⍝ The callback functions of events must begin with '__' (ex.: Click="__Button_Click")
356 ⍝ For 3rd party dll, ⎕USING must be properly initiated before calling this function.
357 ⍝ If there is an error parsing the Xaml, the function will return ⎕NULL with an explanation of the error.
358 ⍝ Parts of code is taken from Dyalog.
359 ⍝
360 ⍝ xamlString = Vector of Characters representing a XAML string
361 ⍝ rootObj = WPF Root Element Object if no error
362 ⍝ = ⎕NULL (explanation of error) if error
363 ⍝
364 ⍝ If an Element has an event attribute that begins with '__' and is named, it will be fixed.
365 ⍝ If an Element has an event attribute that begins with '__' and is not named, it will not be fixed and make a warning.
366 ⍝ If an Element has an event attribute that does not begins with '__', it will make an error and return a ⎕NULL rootObj.
367 ⍝ Function of an event attribute must be defined in the WS otherwise it will not be fixed and make a warning.
368 ⍝ Root element with an event must be named, otherwise it is recommended to be nameless.
369 ⍝ Root element name is removed in all cases. Use the rootObj variable directly to access its properties/methods.
370
371 :Trap 0
372 ⍝ Check if Valid XML
373 ⍝ The following line will bug with an explanation if there is a syntax error in xamlString.
374 ⎕USING∪←⊂'System.Xml,System.Xml.dll'
375 (⎕NEW XmlDocument).LoadXml(⊂xamlString)
376
377 ⍝ The string is valid XML. Clean-it before 'compiling'.
378 data←⎕XML xamlString ⍝ Convert the characters to APL representation of Xml
379 attribs←data[;4] ⍝ Attributes of all the nodes
380 names←{1⊃(((⍵[;1]∊⊂'x:Name')∨(⍵[;1]∊⊂'Name'))/⍵[;2]),⊂''}¨attribs ⍝ Find all 'x:Name' and 'Name' attributes
381 events←⊃⍪/names{(⊂⍺),((⊂'__')≡¨2↑¨⊃¨⍵[;2])⌿⍵}¨attribs ⍝ Events are all attributes with values beginning with '__'
382 data[;4]←{(~(⊂'__')≡¨2↑¨⊃¨⍵[;2])⌿⍵}¨attribs ⍝ Remove the events: attribute definition beginning with '__'
383 data[1;4]←⊂{(~(⊂'x:Class')≡¨7↑¨⊃¨⍵[;1])⌿⍵}⊃data[1;4] ⍝ Remove the x:Class attribute if present in first node
384 xamlString←⎕XML data ⍝ Convert the APL representation of Xml to characters
385 :Else
386 ⍝ There is an Error. Exit.
387 →ERROR
388
389 :EndTrap
390
391 ⍝ Obtain the Root Element Object of the clean-up XAML String.
392 ⍝ You can get an error here if, for example, there is an event that does not begin with '__' and was not remove in Xaml Clean-up.
393 :Trap 0
394 ⎕USING∪←⊂'System.Windows.Markup,WPF/PresentationFramework.dll' ⍝ was ⎕USING←' before
395 rootObj←XamlReader.Parse(⊂xamlString)
396
397 ⍝ ↓↓↓ Alternative way of doing the same thing.
398 ⍝ ⎕USING∪ ← '' 'System.IO' 'System.Xml,system.xml.dll' 'System.Windows,WPF/PresentationFramework.dll' 'System.Windows.Markup'
399 ⍝ rootObj ← XamlReader.Load ⎕NEW XmlTextReader (⎕NEW StringReader (⊂xamlString))
400
401 rootObj.∆Events←events ⍝ Optional: List the events in the property ∆Events
402 :Else
403 ⍝ There is an error. Exit.
404 →ERROR
405
406 :EndTrap
407
408 ⍝ Fix the events of the rootObj before removing its name:
409 ⍝ Will bug if the rootObj does not have a name.
410 :Trap 0
411 :If 1∊events[;1]∊⊂rootObj.Name ⍝ Check if the rootObj has an event
412 :For (ref event expr) :In ↓(events[;1]∊⊂rootObj.Name)⌿events ⍝ Loop through the events
413 caller←(1⊃⎕NSI),'.' ⍝ Namespace that is calling this function
414 expr←((~'#'∊expr)/caller),expr ⍝ Add the namespace of the caller to the name of the event
415 ⍎'rootObj.on',event,'←''',expr,'''' ⍝ Hook-up the event
416 :EndFor
417 :EndIf
418 :Else
419 ⍝ Do nothing. rootObj does not have a name or events to fix.
420
421 :EndTrap
422
423 ⍝ Create refs to all named child objects
424 :Trap 0
425 names←(,⊃0≠⍴¨names)/names ⍝ Keep only the not empty names
426 names←(0=rootObj.⎕NC⊃names)/names ⍝ Only names which do not already have a meaning
427 names←(~names∊⊂rootObj.Name)/names ⍝ Remove the name of the rootObj to prevent a recursive entry.
428 events←(~events[;1]∊⊂rootObj.Name)⌿events ⍝ Remove the event(s) of the rootObj from the list now that they have been fixed.
429 :Else
430 ⍝ Do nothing. The previous 2 lines will bug if rootObj does not have a name.
431
432 :EndTrap
433
434 ⍝ Warns that a name will not be fixed because it is a property or method of the Root Object (ie. name conflict)
435 :Trap 0
436 :If 1∊inter←names∊rootObj.⎕NL-2 3
437 ⎕←'FixXaml Warning - Name(s) not fixed in conflict with Property/Method of Root Object: ',inter/names
438 names←(~inter)/names
439 :EndIf
440
441 :Else
442 ⍝ Do nothing. Root Object does not like ⎕NL
443
444 :EndTrap
445
446 ⍝ Add a reference of all the named object to the rootObj.
447 ⍝ FindName will not find the names on certain object (like template),
448 ⍝ so we need to iterate and Trap the error when the name is not found.
449 :For name :In names
450 :Trap 0
451 ⍎'rootObj.(',name,')←rootObj.FindName ⊂name'
452
453 :Else
454 ⎕←'FixXaml Warning - Name Not found: ',name
455
456 :EndTrap
457 :EndFor
458
459 ⍝ Show a Warning for Events that begins with '__' that will not be fixed because they are nameless:
460 :If 0≠↑⍴inter←(~events[;1]∊names)⌿events
461 ⎕←(⎕UCS 13),'FixXaml Warning - Following Nameless Event(s) Are Not Fixed:'
462 ⎕←inter
463 :End
464
465 ⍝ Hook-up events
466 events←(events[;1]∊names)⌿events ⍝ Named objects only
467 caller←(1⊃⎕NSI),'.' ⍝ Namespace that is calling this function
468
469 :For (ref event expr) :In ↓events
470 :Trap 0
471 ⍝ Add the namespace of the caller to the name of the event
472 expr←((~'#'∊expr)/caller),expr
473
474 :If 0≠⎕NC expr
475 ⍝ Callback function exist. Hook-up the event.
476 ⍎'rootObj.',ref,'.on',event,'←''',expr,''''
477 :Else
478 ⍝ Callback function does not exist. Show warning and do not fix the event.
479 ⎕←'FixXaml Warning - Function ',expr,' does not exist. The Event ''',event,''' of ''',ref,''' is not fixed.'
480 :End
481
482 :Else
483 ⍝ There is an error. Exit.
484 →ERROR
485
486 :EndTrap
487 :EndFor
488
489 →0 ⍝ rootObj is returned here if there is no error.
490
491 ERROR:
492 ⍝ Build the Error Message
493 :If 90≠⎕EN
494 ⍝ APL Error
495 err←(1⊃⎕DM),': ',{(' '=1↑⍵)↓((1↓a,0)∨a←' '≠⍵)/⍵}(2⊃⎕DM),(⎕UCS 13)
496
497 :Else
498 ⍝ .Net Error
499 :If '(NULL)'≢⍕⎕EXCEPTION
500 ⍝ Show the value of ⎕EXCEPTION if not (NULL).
501 err←('EXCEPTION: ',⎕EXCEPTION.Message),(⎕UCS 13)
502 :Else
503 ⍝ If ⎕EXCEPTION is (NULL) than the .Message property is empty.
504 err←'EXCEPTION: Unknown error',(⎕UCS 13)
505
506 :EndIf
507
508 :End
509
510 rootObj←⎕NULL err
511 ∇
512
513 ∇ winParent←GetWindowParent object
514 ⍝ Obtain the Windows Parent (Root Object) of a children's element.
515
516 winParent←object
517
518 :While 'System.Windows.Window'≢winParent.GetType.ToString
519 winParent←winParent.Parent
520 :EndWhile
521 ∇
522
523 ∇ bmpimg←ImageFromBase64String base64String;imageBytes;MS;⎕USING
524 ⍝ Convert a Base64String to a System.Windows.Media.Imaging.BitmapImage.
525
526 ⎕USING←'System.IO,mscorlib.dll' 'System,mscorlib.dll' 'System.Windows.Media.Imaging,WPF/PresentationCore.dll'
527
528 ⍝ Convert Base64 String to byte[] as numbers.
529 imageBytes←Convert.FromBase64String(⊂base64String)
530
531 ⍝ Create a new MemoryStream with the byte[]
532 MS←⎕NEW MemoryStream(⊂imageBytes)
533
534 ⍝ Create a BitmapImage Object from the Memory Stream
535 bmpimg←⎕NEW BitmapImage
536 bmpimg.BeginInit
537 ⍝ The .OnLoad CacheOption will load the MemoryStream right now so it can be dispose.
538 ⍝ That way there is no need to use a WriteableBitmap.
539 bmpimg.CacheOption←bmpimg.CacheOption.OnLoad
540 bmpimg.StreamSource←MS
541 bmpimg.EndInit
542
543 ⍝ ⍝ Create a WriteableBitmap that does not need the MemoryStream to persist
544 ⍝ ⍝ That way it is possible to erase the MemoryStream after creating the Image
545 ⍝ bmpimg←⎕NEW WriteableBitmap bmpimg
546
547 ⍝ Erase the MemoryStream
548 MS.Close ⋄ MS.Dispose ⋄ MS←⎕NULL
549 ∇
550
551 ∇ ScriptFollowsDispatchDelegate obj;actions;delegate;dtlb;⎕IO;⎕ML;⎕USING
552 ⍝ Function to write asynchronously to the UI thread from another thread.
553 ⍝ The calling thread does not wait for the operation to finish.
554 ⍝ Treat following commented lines in caller as a script.
555 ⍝ Lines beginning with ⍝∇ are kept
556 ⍝ Lines beginning with ⍝∇⍝ are stripped out (comments)
557
558 ⍝ obj = UI Object that you want to write to from another thread
559 ⍝ actions = Lines to execute in the UI thread.
560
561 (⎕IO ⎕ML)←1 3
562
563 :Trap 0
564 ⎕USING←'System,System.dll' 'System.Windows.Threading,WPF/WindowsBase.dll'
565
566 ⍝ Create a function (⍙Delegate) with the 'action' to execute in the UI thread.
567 ⍝ The function will be executed where 'DispatchDelegate' is called and not where
568 ⍝ 'DispatchDelegate' is located.
569 dtlb←{⍵{((∨\⍵)∧⌽∨\⌽⍵)/⍺}' '≠⍵}
570 actions←{{'⍝'=↑⍵:'' ⋄ ' ',dtlb ⍵}¨2↓¨⍵/⍨∧\(⊂'⍝∇')≡¨2↑¨⍵}dtlb¨(1+2⊃⎕LC)↓⎕NR 2⊃⎕XSI
571 delegate←(⎕IO⊃⎕RSI).⎕OR(⎕IO⊃⎕RSI).⎕FX(⊂'⍙Delegate'),actions,(⊂'⎕EX ''⍙Delegate''')
572
573 ⍝ Get a 'Dispatcher' from the UI object. That way we are sure to have the right UI thread.
574 ⍝ Use the method '.Invoke' instead of '.BeginInvoke' for synchronous call.
575 {}obj.Dispatcher.BeginInvoke(DispatcherPriority.Normal(⎕NEW Action delegate))
576
577 :Else
578 ⎕←'Error ScriptFollowsDispatchDelegate: ',actions
579
580 ⍝ Returns the Last Error
581 :If 90=⎕EN
582 ⎕←'EXCEPTION: ',⎕EXCEPTION.Message
583 :Else
584 ⎕←(1⊃⎕DM),': ',(2⊃⎕DM)
585 :EndIf
586 :End
587 ∇
588
589 ∇ rootObj←ScrubAndFix xamlString;err;names;nodeNumber;reader;stringReader;writer
590 ⍝ Function to remove the Class and Events elements of Xaml and fix the resulting Xaml.
591 ⍝ Each named element(s) object will be attached to rootObject.
592 ⍝ Root element name is removed in all cases. Use the rootObj directly to access its properties/methods.
593 ⍝ This function is most usefull when experimenting with Xaml taken directly from the Web but is slower than FixXaml.
594 ⍝ Inspired from the code of XAMLPAD2009.
595 ⍝
596 ⍝ XamlString = Vector of Characters representing a XAML string
597 ⍝ rootObj = WPF Root Element Object if no error
598 ⍝ = ⎕NULL (explanation of error) if error
599
600 :Trap 0
601
602 ⎕USING∪←'System.IO' 'System.Windows.Markup,WPF/PresentationFramework.dll' 'System.Xaml,System.Xaml.dll'
603 stringReader←⎕NEW StringReader(⊂xamlString)
604 reader←⎕NEW XamlXmlReader(stringReader XamlReader.GetWpfSchemaContext)
605 writer←⎕NEW XamlObjectWriter(reader.SchemaContext)
606
607 ⎕USING←0⍴⊂''
608 names←'' ⍝ Initial value of the names to fix.
609 nodeNumber←0 ⍝ Initial value of the node number.
610
611 :While reader.Read
612
613 :If 'StartObject'≡⍕reader.NodeType
614 ⍝ Will increment of 1 each time a new node (with a new object) begins.
615 nodeNumber+←1
616 :End
617
618 :If 'StartMember'≡⍕reader.NodeType
619 :AndIf reader.Member.Name≡'Class'
620 {}reader.Read
621 {}reader.Read
622
623 :ElseIf 'StartMember'≡⍕reader.NodeType
624 :AndIf reader.Member.IsEvent
625 {}reader.Read
626 {}reader.Read
627
628 :ElseIf 'StartMember'≡⍕reader.NodeType
629 :AndIf reader.Member.Name≡'Name'
630 writer.WriteNode(reader)
631 {}reader.Read
632 writer.WriteNode(reader)
633
634 ⍝ Check if reader is on first node
635 :If 1≠nodeNumber
636 ⍝ reader is not on first node. Keep the name.
637 names,←⊂reader.Value
638 :Else
639 ⍝ reader is on first node. Don't keep the name.
640 :End
641
642 {}reader.Read
643 writer.WriteNode(reader)
644
645 :Else
646 writer.WriteNode(reader)
647
648 :End
649
650 :EndWhile
651
652 rootObj←writer.Result
653
654 ⍝ Assign the value of each names found to the root object:
655 :If 0≠⍴names
656 rootObj{⍎'⍺.',⍵,'←⍺.FindName(⊂,⍵)'}¨names
657 :Else
658 ⍝ Do nothing, there is no names.
659 :End
660
661 :Else
662 ⍝ Build the Error Message
663 :If 90≠⎕EN
664 ⍝ APL Error
665 err←(1⊃⎕DM),': ',{(' '=1↑⍵)↓((1↓a,0)∨a←' '≠⍵)/⍵}(2⊃⎕DM),(⎕UCS 13)
666
667 :Else
668 ⍝ .Net Error
669 :Trap 0
670 ⍝ Show the value of ⎕EXCEPTION.Message if not ⎕NULL.
671 err←('EXCEPTION: ',⎕EXCEPTION.Message),(⎕UCS 13)
672 :Else
673 ⍝ Sometimes ⎕EXCEPTION is (NULL) and will bug here.
674 err←'Exception (NULL): Unknown error',(⎕UCS 13)
675
676 :EndTrap
677
678 :End
679
680 rootObj←⎕NULL err
681
682 :EndTrap
683 ∇
684
685 ∇ __Button_Click(sender event);rootObject;⎕USING
686 ⍝ Click Event Handler for the Button
687
688 ⍝ Get the Root Object from the Button object (sender)
689 rootObject←GetWindowParent sender
690
691 ⍝ Assign the new text to the TextBox.
692 rootObject.textBox1.Text←'I Was Clicked !'
693
694 ⍝ Change some colors of the TextBox
695 ⎕USING←'System.Windows.Media,WPF/PresentationCore.dll' 'System.Windows,WPF/PresentationFramework.dll'
696 rootObject.textBox1.Background←⎕NEW SolidColorBrush(Colors.Yellow)
697 rootObject.textBox1.BorderBrush←⎕NEW SolidColorBrush(Colors.Red)
698 rootObject.textBox1.BorderThickness←⎕NEW Thickness 3
699 ∇
700
701 ∇ __EventHandler(sender event);name
702 ⍝ Single Event Handler for the Window
703
704 ⍝ Get name of the control that was clicked
705 name←event.Source.Name
706
707 ⍝ sender is the Root Object in this case because
708 ⍝ the routed event was attached to it.
709 sender.lStatusBar.Content←'I Was Clicked: ',name
710
711 ⍝ Select the code to be executed:
712 :Select name
713 :Case 'mnuCut'
714
715 :Case 'mnuCopy'
716
717 :Case 'mnuPaste'
718
719 :Case 'mnuPrint'
720
721 :Case 'mnuQuit'
722
723 :Case 'mnuAbout'
724
725 :Case 'btnButton1'
726
727 :Case 'btnButton2'
728
729 :Case 'btnButton3'
730
731 :Else
732 'Error: Unknow Name'
733 :EndSelect
734 ∇
735
736 ⍝ Section BackgroundWorker
737
738 ∇ BackgroundWorkerSample max;xaml
739 ⍝ If you have an operation that will take a long time to complete, and you do not want to cause delays in your
740 ⍝ user interface (UI), you can use the BackgroundWorker class from Microsoft to run the operation on another thread.
741 ⍝
742 ⍝ The BackgroundWorker offers several features which include spawning a background thread, the ability
743 ⍝ to cancel the background process before it has completed, and the chance to report the progress back to your UI.
744 ⍝
745 ⍝ For multithread operation with APL it is recommended to wait on the Window on a different thread,
746 ⍝ that way the thread 0 of the session is not blocked. So the Window will wait on thread 1 and the
747 ⍝ long calculation will be done on tread 2.
748 ⍝
749 ⍝ This function will simulate a long calculation with the use of a BackgroundWorker.
750 ⍝ It is finding all the numbers that are a multiple of 42 between 1 and 'max'
751 ⍝ Start the demo function by doing: BackgroundWorkerSample& 1000
752 ⍝ In this case it will find all the multiple of 42 between 1 and 1000.
753 ⍝ The Spawn operator '&' is telling APL to run the function on another thread (in our case thread no 1)
754 ⍝
755 ⍝ BackgroundWorkerSample = Main function
756 ⍝ __btnDoAsynchronousCalculation_Click = Callback of the 'Start' button
757 ⍝ __btnCancelAsynchronousCalculation_Click = Callback of the 'Cancel' button
758 ⍝ __worker_DoWork = Does the long calculation on another thread (in our case thread no 2)
759 ⍝ __worker_ProgressChanged = Change the UI to show the progress. Executed on thread no 1 (UI).
760 ⍝ __worker_RunWorkerCompleted = Callback when the DoWork callback is finished. Executed on thread no 1 (UI).
761
762 ⍝ Inspired from the following:
763 ⍝ http://www.wpf-tutorial.com/misc/multi-threading-with-the-backgroundworker/
764 ⍝ http://www.wpf-tutorial.com/misc/cancelling-the-backgroundworker/
765 ⍝ http://www.jeremybytes.com/downloads/backgroundworkerinwpf.pdf
766 ⍝ https://msdn.microsoft.com/fr-fr/library/cc221403(v=vs.95).aspx
767
768 {}2520⌶1 ⍝ Use separate thread for .Net
769
770 ⎕USING←''
771 ⎕USING,←⊂'System,mscorlib.dll'
772 ⎕USING,←⊂'System.Threading,mscorlib.dll'
773 ⎕USING,←⊂'System.ComponentModel,System.dll'
774 ⎕USING,←⊂'System.Windows,WPF/PresentationFramework.dll'
775
776 xaml←'<Window'
777 xaml,←' xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"'
778 xaml,←' xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"'
779 xaml,←' Height="300"'
780 xaml,←' Width="375"'
781 xaml,←' Title="BackgroundWorkerSample">'
782 xaml,←' <DockPanel Margin="10">'
783 xaml,←' <DockPanel DockPanel.Dock="Top">'
784 xaml,←' <Button'
785 xaml,←' Name="btnDoAsynchronousCalculation"'
786 xaml,←' HorizontalAlignment="Left"'
787 xaml,←' Width="150"'
788 xaml,←' Click="__btnDoAsynchronousCalculation_Click"'
789 xaml,←' IsEnabled="True"'
790 xaml,←' DockPanel.Dock="Left">Start'
791 xaml,←' </Button>'
792 xaml,←' <Button'
793 xaml,←' Name="btnCancel"'
794 xaml,←' HorizontalAlignment="Right"'
795 xaml,←' Width="150"'
796 xaml,←' Click="__btnCancelAsynchronousCalculation_Click"'
797 xaml,←' IsEnabled="False"'
798 xaml,←' DockPanel.Dock="Right">Cancel'
799 xaml,←' </Button>'
800 xaml,←' </DockPanel>'
801 xaml,←' <ProgressBar Name="pbCalculationProgress" Height="18" DockPanel.Dock="Bottom"/>'
802 xaml,←' <ListBox Name="lbResults" Margin="0,10"/>'
803 xaml,←' </DockPanel>'
804 xaml,←'</Window>'
805
806 :If ⎕NULL≡↑win←FixXaml xaml
807 ⍝ Fixing the Xaml did not work. Show the error and exit.
808 ⎕←2⊃win
809
810 :Else
811 ⍝ There is no error.
812 win.max←max
813 {}win.ShowDialog
814
815 :EndIf
816 ∇
817
818 ∇ __btnDoAsynchronousCalculation_Click(sender event)
819 ⍝ Function using a 'BackgroundWorker' thread to do long calculation or blocking action on another thread.
820
821 ⍝ The ProgressBar and ListBox are reset
822 win.pbCalculationProgress.Value←0
823 win.lbResults.Items.Clear
824
825 ⍝ Get a BackgroundWorker object from System.ComponentModel in System.dll
826 win.worker←⎕NEW BackgroundWorker
827
828 ⍝ The event 'DoWork' occurs when the method 'RunWorkerAsync' is called.
829 ⍝ The event handler executes on another thread the time-consuming operation.
830 ⍝ You cannot access the UI thread from this callback.
831 win.worker.onDoWork←'__worker_DoWork'
832
833 ⍝ The event 'ProgressChanged' occurs when the method 'ReportProgress' is called within the 'DoWork' event function (__worker_DoWork).
834 ⍝ The 'ProgressChanged' event handler executes on the thread that created the BackgroundWorker (should be the UI thread).
835 win.worker.WorkerReportsProgress←1 ⍝ Specify that you want the background operation to report progress.
836 win.worker.onProgressChanged←'__worker_ProgressChanged'
837
838 ⍝ The event 'RunWorkerCompleted' occurs when the DoWork event handler returns.
839 win.worker.onRunWorkerCompleted←'__worker_RunWorkerCompleted'
840
841 ⍝ Specify you want the background operation to allow cancellation.
842 win.worker.WorkerSupportsCancellation←1
843
844 ⍝ Starts execution of the background operation by raising the 'DoWork' event asynchronously.
845 ⍝ The .IsBusy property can be used to check if the worker is already running.
846 win.worker.RunWorkerAsync win.max
847
848 ⍝ The previous line returns immediately so we can set the properties of the buttons.
849 win.btnDoAsynchronousCalculation.IsEnabled←0
850 win.btnCancel.IsEnabled←1
851 ∇
852
853 ∇ __btnCancelAsynchronousCalculation_Click(sender event)
854 ⍝ To cancel the calculation execute the method .CancelAsync of the BackgroundWorker
855 ⍝ This will sets the CancellationPending property to true of the BackgroundWorker
856 ⍝ The function of the 'DoWork' event should periodically check the CancellationPending property to see if it has been set to true.
857
858 ⍝ event = System.Windows.RoutedEventArgs
859
860 win.worker.CancelAsync
861 ∇
862
863 ∇ __worker_DoWork(sender event);errorException;errorMessage;i;max;progressPercentage;result
864 ⍝ Event handler executed on another thread when the method 'RunWorkerAsync' is called on the BackgroundWorker object.
865 ⍝ If your background operation requires a parameter, call 'RunWorkerAsync' with your parameter.
866 ⍝ You can extract the parameter from the 'DoWorkEventArgs.Argument' property.
867 ⍝
868 ⍝ You must be careful not to manipulate any user-interface objects in your 'DoWork' event handler.
869 ⍝ Instead, communicate to the user interface through 'ProgressChanged' and 'RunWorkerCompleted' events.
870 ⍝
871 ⍝ event = System.ComponentModel.DoWorkEventArgs
872
873 ⍝ It is recommended to put the calculations executed on this other thread inside a ':Trap' statement
874 ⍝ and report the error(s) on the UI thread via an 'ArgumentException'.
875 ⍝ This make it easier to debug and to report the error.
876
877 {}2501⌶0 ⍝ Discard thread on exit
878
879 :Trap 0
880 max←event.Argument ⍝ Get the argument of the 'RunWorkerAsync' method.
881
882 result←⍳0
883
884 ⍝ Find all the number divisible by 42 from 1 to 'max'
885 :For i :In ⍳max
886
887 ⍝ Test if the Cancel button was clicked
888 :If sender.CancellationPending
889 event.Cancel←1
890 →END
891
892 :Else
893 ⍝ No cancellation. Do the next calculation.
894
895 progressPercentage←Convert.ToInt32(100×i÷max) ⍝ Must be an Int32. (Not coerce by APL)
896
897 ⍝ Do the calculation and report progress on the UI with the '.ReportProgress' method of the BackgroundWorker.
898 :If 0=42|i
899 ⍝ 'i' is a multiple of 42
900 result,←i
901
902 ⍝ The first argument will be in event.ProgressPercentage (Int32)
903 ⍝ The second argument (optional) will be in event.UserState (object)
904 sender.ReportProgress(progressPercentage,i)
905
906 :Else
907 ⍝ 'i' is not a multiple of 42
908 sender.ReportProgress(progressPercentage)
909
910 :EndIf
911 :EndIf
912
913 ⍝ Simulate a long calculation by blocking the thread artificially
914 Thread.Sleep 10 ⍝ With Thread.Sleep 1 it does not work. APL too fast for Windows ?
915
916 :EndFor
917
918 END:
919 ⍝ ↓↓↓ This will call the event 'RunWorkerCompleted' with an argument in the .Result property.
920 event.Result←max result
921
922 :Else
923
924 ⍝ There has been an error. Build the error message
925 :If 90≠⎕EN
926 ⍝ APL Error
927 errorMessage←(1⊃⎕DM),': ',{(' '=1↑⍵)↓((1↓a,0)∨a←' '≠⍵)/⍵}(2⊃⎕DM),(⎕UCS 13)
928
929 :Else
930 ⍝ .Net Error
931 :If '(NULL)'≢⍕⎕EXCEPTION
932 ⍝ Show the value of ⎕EXCEPTION if not (NULL).
933 errorMessage←('EXCEPTION: ',⎕EXCEPTION.Message),(⎕UCS 13)
934 :Else
935 ⍝ If ⎕EXCEPTION is (NULL) than the .Message property is empty.
936 errorMessage←'EXCEPTION: Unknown error',(⎕UCS 13)
937
938 :EndIf
939 :End
940
941 ⍝ This Exception will terminate the iteration and call the 'RunWorkerCompleted' event.
942 ⍝ The error can be obtained in the function '__worker_RunWorkerCompleted' that is running on the UI thread.
943 errorException←⎕NEW ArgumentException(⊂errorMessage)
944 errorException ⎕SIGNAL 90
945
946 :EndTrap
947 ∇
948
949 ∇ __worker_ProgressChanged(sender event)
950 ⍝ Callback function of the event 'ProgressChanged'
951 ⍝ It is excuted on the thread that created the BackgroundWorker
952 ⍝ The UI can be access from this function
953 ⍝
954 ⍝ event = System.ComponentModel.ProgressChangedEventArgs
955
956 ⍝ Get first argument
957 win.pbCalculationProgress.Value←event.ProgressPercentage
958
959 ⍝ Get second argument of callback if not [Null].
960 :If '[Null]'≢⍕event.get_UserState
961 {}win.lbResults.Items.Add(event.UserState)
962
963 ⍝ Position the ListBox at the end.
964 win.lbResults.ScrollIntoView(win.lbResults.Items[win.lbResults.Items.Count-1])
965 :EndIf
966 ∇
967
968 ∇ __worker_RunWorkerCompleted(sender event);max;result
969 ⍝ This event is raised when the DoWork event handler returns.
970 ⍝ It is excuted on the thread that created the BackgroundWorker
971 ⍝ The UI can be access from this function
972 ⍝
973 ⍝ event = System.ComponentModel.RunWorkerCompletedEventArgs
974
975 ⍝ Check if it was cancelled
976 :If event.Cancelled
977 {}MessageBox.Show(⊂'The calculation was Cancel')
978
979 ⍝ Check if there was an error
980 :ElseIf '[Null]'≢⍕event.get_Error
981 ⍝ The 'errorMessage' of '__worker_DoWork' is in 'event.Error.Message'
982 {}MessageBox.Show(⊂event.Error.Message)
983
984 :Else
985 ⍝ The argument passed by '__worker_DoWork' is in 'event.Result'
986 (max result)←event.Result
987 {}MessageBox.Show(⊂'Numbers between 1 and ',(⍕max),' divisible by 42: ',⍕result)
988
989 :EndIf
990
991 ⍝ Setup the UI for another calculation
992 win.btnDoAsynchronousCalculation.IsEnabled←1
993 win.btnCancel.IsEnabled←0
994 win.pbCalculationProgress.Value←0
995
996 ⍝ Clean-up
997 win.worker.Dispose
998 ∇
999
1000 :EndNamespace
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.