ブログ

割とコンピュータよりの情報をお届けします。

コンピュータ

C#で配列のソート

C#で配列のソートをする方法としてArray.Sortがある.

ただし,引数に与えた配列は順番が破壊されてしまう.

通常は,以下のようにするが,これだと元のtestは書き換えられる.

            Int32[] test = new Int32[5];
            
            for (int i = 0; i < test.Length; i++)
            {
                test[i] = test.Length - i;
            }
            Array.Sort(test);

もとの配列の中でのインデックスを記録しておきたい場合,test1にインデックスを記録しておき,Array.Sortに二つ配列を渡してやると,test1はソート前の配列での順番を表すことになる.

            Int32[] test1 = new Int32[5];
            Int32[] test2 = new Int32[5];
            
            Random rand = new Random(100);
            for (int i = 0; i < test1.Length; i++)
            {
                test1[i] = i;
                test2[i] = rand.Next();
            }
            Array.Sort(test2, test1);
 

≫ 続きを読む

2018/12/28 コンピュータ   TakeMe

Windowsタスクバーを表示したり非表示にしたり

Windows Embedded Standardの装置でタスクバーを非表示にしている例があった.最初はスタートメニューにそのような設定項目があるのかと思っていたが,どうもそうではないらしい.どのように行っているのか確認していると...

サンプルとして以下のようなコードで実施できる.

#include "stdafx.h"
#include <Windows.h>

int main()
{
    HWND hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);

    ShowWindow(hWnd, IsWindowVisible(hWnd) ? SW_HIDE : SW_SHOW);

    return 0;
}

大したことのないアプリである.以下のようなコードでもよいです(Windows 10ではこれで動いていた).

#include "stdafx.h"
#include "WindowsProject2.h"


int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    HWND hWnd = FindWindow(_T("Shell_TrayWnd"), NULL);
    ShowWindow(hWnd, IsWindowVisible(hWnd) ? SW_HIDE : SW_SHOW);
    return 0;
}

≫ 続きを読む

2018/12/05 コンピュータ   TakeMe

Visual Studio 2017ならWindows アプリケーションがテンプレートですぐに

猫でもわかるWindowsプログラミング を買ってからすでに,十数年たっているが,今でも十分に使える説明が多い。買った頃は,BCCでコンパイルしていた.

Windows Embedded Compact 用のアプリケーションもほぼ同じ説明で作れる

Visual Studio 2017なら最初の空のウィンドウ(メニューバー付き)を作るまでテンプレートで出来てしまう。

Visual Studio 2017ならプロジェクトを新規作成するときのダイアログで,Visual C++の項目Windows デスクトップ アプリケーションを選択すると,一気にウィンドウ作成まで行ってしまう.

説明との,違いといえば最近のバージョンのWindows(Windows Embedded Compactを含む)はWCHARが標準になっているところである.

つまり文字の処理関係が変わっている点だけ注意が必要である.しかし,説明自体は非常によくできている.

≫ 続きを読む

2018/12/02 コンピュータ   TakeMe

Visual C++プロジェクトでアセンブリ出力という機能

Visual C++でプロジェクトを作っていれば,アッセンブリ出力という機能が使えることを知った。

プロジェクトのプロパティで[C/C++]->[すべてのオプション]->アッセンブリの出力で「アッセンブリコード、コンピューター語、ソースコード(/FAcs)」を出力するようにすれば,

#include "stdafx.h"


int main()
{
    signed char a;
    short b;
    int c;

    a = -10;
    b = 20;
    c = 30;
    c = a + b + c;
    return 0;
}

このコードが,*.codファイルに出力される。

; Listing generated by Microsoft (R) Optimizing Compiler Version 19.13.26129.0 

    TITLE    E:\start001\ConsoleApplication1\ConsoleApplication1.cpp
    .686P
    .XMM
    include listing.inc
    .model    flat

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC    _main
EXTRN    __RTC_InitBase:PROC
EXTRN    __RTC_Shutdown:PROC
;    COMDAT rtc$TMZ
rtc$TMZ    SEGMENT
__RTC_Shutdown.rtc$TMZ DD FLAT:__RTC_Shutdown
rtc$TMZ    ENDS
;    COMDAT rtc$IMZ
rtc$IMZ    SEGMENT
__RTC_InitBase.rtc$IMZ DD FLAT:__RTC_InitBase
rtc$IMZ    ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File c:\start001\consoleapplication1\consoleapplication1.cpp
;    COMDAT _main
_TEXT    SEGMENT
_c$ = -32                        ; size = 4
_b$ = -20                        ; size = 2
_a$ = -5                        ; size = 1
_main    PROC                        ; COMDAT

  00000    55         push     ebp
  00001    8b ec         mov     ebp, esp
  00003    81 ec e4 00 00
    00         sub     esp, 228        ; 000000e4H
  00009    53         push     ebx
  0000a    56         push     esi
  0000b    57         push     edi
  0000c    8d bd 1c ff ff
    ff         lea     edi, DWORD PTR [ebp-228]
  00012    b9 39 00 00 00     mov     ecx, 57            ; 00000039H
  00017    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  0001c    f3 ab         rep stosd

  0001e    c6 45 fb f6     mov     BYTE PTR _a$[ebp], -10    ; fffffff6H

  00022    b8 14 00 00 00     mov     eax, 20            ; 00000014H
  00027    66 89 45 ec     mov     WORD PTR _b$[ebp], ax

  0002b    c7 45 e0 1e 00
    00 00         mov     DWORD PTR _c$[ebp], 30    ; 0000001eH

  00032    0f be 45 fb     movsx     eax, BYTE PTR _a$[ebp]
  00036    0f bf 4d ec     movsx     ecx, WORD PTR _b$[ebp]
  0003a    03 45 e0     add     eax, DWORD PTR _c$[ebp]
  0003d    03 c8         add     ecx, eax
  0003f    89 4d e0     mov     DWORD PTR _c$[ebp], ecx

  00042    33 c0         xor     eax, eax

  00044    5f         pop     edi
  00045    5e         pop     esi
  00046    5b         pop     ebx
  00047    8b e5         mov     esp, ebp
  00049    5d         pop     ebp
  0004a    c3         ret     0
_main    ENDP
_TEXT    ENDS
END

x64の場合には以下のようになる

; Listing generated by Microsoft (R) Optimizing Compiler Version 19.13.26129.0 

include listing.inc

INCLUDELIB MSVCRTD
INCLUDELIB OLDNAMES

PUBLIC    main
EXTRN    _RTC_InitBase:PROC
EXTRN    _RTC_Shutdown:PROC
;    COMDAT pdata
pdata    SEGMENT
$pdata$main DD    imagerel $LN3
    DD    imagerel $LN3+82
    DD    imagerel $unwind$main
pdata    ENDS
;    COMDAT rtc$TMZ
rtc$TMZ    SEGMENT
_RTC_Shutdown.rtc$TMZ DQ FLAT:_RTC_Shutdown
rtc$TMZ    ENDS
;    COMDAT rtc$IMZ
rtc$IMZ    SEGMENT
_RTC_InitBase.rtc$IMZ DQ FLAT:_RTC_InitBase
rtc$IMZ    ENDS
;    COMDAT xdata
xdata    SEGMENT
$unwind$main DD    05051c01H
    DD    010a030dH
    DD    070030025H
    DD    05002H
xdata    ENDS
; Function compile flags: /Odtp /RTCsu /ZI
; File e:\start001\consoleapplication1\consoleapplication1.cpp
;    COMDAT main
_TEXT    SEGMENT
a$ = 4
b$ = 36
c$ = 68
main    PROC                        ; COMDAT

$LN3:
  00000    40 55         push     rbp
  00002    57         push     rdi
  00003    48 81 ec 28 01
    00 00         sub     rsp, 296        ; 00000128H
  0000a    48 8b ec     mov     rbp, rsp
  0000d    48 8b fc     mov     rdi, rsp
  00010    b9 4a 00 00 00     mov     ecx, 74            ; 0000004aH
  00015    b8 cc cc cc cc     mov     eax, -858993460        ; ccccccccH
  0001a    f3 ab         rep stosd

  0001c    c6 45 04 f6     mov     BYTE PTR a$[rbp], -10

  00020    b8 14 00 00 00     mov     eax, 20
  00025    66 89 45 24     mov     WORD PTR b$[rbp], ax

  00029    c7 45 44 1e 00
    00 00         mov     DWORD PTR c$[rbp], 30

  00030    0f be 45 04     movsx     eax, BYTE PTR a$[rbp]
  00034    0f bf 4d 24     movsx     ecx, WORD PTR b$[rbp]
  00038    8b 55 44     mov     edx, DWORD PTR c$[rbp]
  0003b    03 d0         add     edx, eax
  0003d    8b c2         mov     eax, edx
  0003f    03 c8         add     ecx, eax
  00041    8b c1         mov     eax, ecx
  00043    89 45 44     mov     DWORD PTR c$[rbp], eax

  00046    33 c0         xor     eax, eax

  00048    48 8d a5 28 01
    00 00         lea     rsp, QWORD PTR [rbp+296]
  0004f    5f         pop     rdi
  00050    5d         pop     rbp
  00051    c3         ret     0
main    ENDP
_TEXT    ENDS
END

≫ 続きを読む

2018/11/24 コンピュータ   TakeMe

.NET Framework Semaphoreを使ってみた

.NET Frameworkでは結構前のバージョンからSystem.Threading.Semaphoreなるものが使えるようになっている。

例えば次のようなコードだが,Semaphoreをnamespaceに使ってしまったので,System.Threading.Semaphoreをいちいち書いている。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Threading;

namespace Semaphore
{
    class Program
    {
        private static System.Threading.Semaphore sem;

        static void Main(string[] args)
        {
            sem = new System.Threading.Semaphore(0, 1);

            for (int i = 1; i <= 10; i++)
            {
                Thread t = new Thread(new ParameterizedThreadStart(Worker));
                t.Start(i);
            }

            Thread.Sleep(500);

            Console.WriteLine("Main thread calls Release(1).");
            sem.Release(1);

            Console.WriteLine("Main thread exits.");
        }

        private static void Worker(object num)
        {
            Console.WriteLine("Thread {0} started " +
                "and waits for the semaphore.", num);
            sem.WaitOne();
            {
                // ここに一スレッドごと実行したい内容
                Console.WriteLine("Thread {0} enters the semaphore.", num);
            }
            Int32 count = sem.Release(1);
            Console.WriteLine("Thread {0} releases the semaphore. " +
                "The previous semaphore cout: {1}",
                num, count);
        }
    }
}

実はmutexより速いが,lockなどより時間がかかるらしい。

≫ 続きを読む

2018/11/18 コンピュータ   TakeMe

WPFでTextBox内で上下キーでフォーカスを遷移

WPFでTextBoxにフォーカスが当たっているときに上下キーを押すとフォーカスを遷移できる仕組みを実装していた。

xamlにはTextBoxが複数並べた。
そのTextBoxにはKeyUpのイベントハンドラを設定している。

<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" KeyUp="TextBox_KeyUpEvent"/>

コードビハインドでは以下のように設定を追加してみた。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void TextBox_KeyUpEvent(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Down)
            {
                var direction = FocusNavigationDirection.Next;
                (FocusManager.GetFocusedElement(this) as FrameworkElement)?.MoveFocus(new TraversalRequest(direction));
            } else if (e.Key == Key.Up)
            {
                var direction = FocusNavigationDirection.Previous;
                (FocusManager.GetFocusedElement(this) as FrameworkElement)?.MoveFocus(new TraversalRequest(direction));
            }
        }
    }
}

FocusNavigationDirection.Nextとか,FocusNavigationDirection.Previousとかはよいが,?を使った書法は参考ページにあったものだが,珍しい書き方だったので引用してしまった。
もし私がコーディングしたら以下のようになる(かな)

private void TextBox_KeyUpEvent(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Down)
            {
                var direction = FocusNavigationDirection.Next;
                FrameworkElement element = (FrameworkElement)FocusManager.GetFocusedElement(this);
                if (element != null)
                    element.MoveFocus(new TraversalRequest(direction));
            } else if (e.Key == Key.Up)
            {
                var direction = FocusNavigationDirection.Previous;
                FrameworkElement element = (FrameworkElement)FocusManager.GetFocusedElement(this);
                if (element != null)
                    element.MoveFocus(new TraversalRequest(direction));
            }
        }

≫ 続きを読む

2018/10/13 コンピュータ   TakeMe
タグ:WPF

node.js pkgは10.xの最新系に非対応?(一緒に入れているPythonのバージョン問題か?)

node.js pkgをいろいろ試しているとnode-v10.2.xくらいは問題なく動くが,一部のバージョンを入れている環境では失敗していた。

普通はnode-v10.11.0-win-x64でも以下のコマンドで1ファイル化が完了する。

npm install -D pkg
npx pkg serv.js

実行しても環境によっては失敗する。
対策は,nodevars.batに
set "PATH=C:\WinPython-64bit-2.7.13.1Zero\python-2.7.13.amd64;%PATH%"
を追加してみることしか策を持っていない。

Python 3.7が動くようにしてると失敗するだけかもしれない

一応,pkgはPython無しでも動くはずなのに。
 

≫ 続きを読む

2018/10/07 コンピュータ   TakeMe
タグ:Node.js

statnett/vue-plotlyでWebGLをサポートしていないような表示が出る問題

昨日のとある作業で,statnett/vue-plotlyでWebGLをサポートしていないような表示が出る問題が発生して作業が止まってしまった。
"Webgl is not supported by your browser" しかし,WebブラウザはWebGLをサポートはしているのだ。

結局どうすればよいのかということであるが,このパッケージ自体はvue.jsラッパーで大きな内容は書かれていない。
そこで,パッケージ内(node_modules/@statnett/vue-plotly/)Plotly.vueをコピーして手動でimportしてやればよい。
ただし,それではなにも状況が変化しない。
そこで,
import Plotly from 'plotly.js'

import Plotly from 'plotly.js/dist/plotly.min.js'
でおき変える。

これで,この単一ファイルコンポーネントimportすれば使える。

≫ 続きを読む

2018/10/02 コンピュータ   TakeMe

Zipファイルから手動インストールしたNode.jsでnpmアップデート

Zipファイルから手動インストールしたNode.jsでnpmアップデートしようとすると
npm ERR! Refusing to delete C:\node-v10.2.1-win-x64\npm.cmd: is outside C:\node-v10.2.1-win-x64\node_modules\npm and not a link
npm ERR! File exists: C:\node-v10.2.1-win-x64\npm.cmd
npm ERR! Move it away, and try again.
などと出てきてアップデートできない。

何とかならないのかを調べていたら見つかった
最初見逃していたのは「mvn環境」って何,と思っていたから。

参考のページを見ていただくとわかるのだが,実行中のnpmは自分を消せないのだ。
そこでnpm.cmdをnpm2.cmdなどにへんこうしておき,node_modulesの中のnpmの名前を例えばnpm2などに変更しておく。そうすると,npm.cmdが使えなくなるので,直接
node node_modules\npm2\bin\npm-cli.js i -g npm@latest
を実行すればよいというもの。

なるほど。

一応 次の方法でもできないかなー
npm更新用のフォルダで
npm init -y
npm install -D npm
npx npm i -g npm@latest

≫ 続きを読む

2018/09/30 コンピュータ   TakeMe
タグ:Node.js

node.js pkgで1ファイル実行ファイル化

Node.jsでプログラムを配布する際にいちいちNode.jsやパッケージファイルを一緒に提供する必要があるとかなり管理が大変になる。もちろん,JavaScriptのアプリケーションだけがたくさん種類がある場合にはこの限りではないが,一つのアプリを提供するのにファイルがたくさんあるのはあまりやりたくない。

具体的な方法は,pkgを使うということ。
npm install -g pkg
でインストールをする。

これだけで例えばexpressのサーバserv.jsなどを作っていた場合,
pkg serv.js
で実行ファイルが作り始められる。
(npm install -D pkgとした場合にはnpx pkg serv.js)
この時,なにも指定していなければWindows用かLinux用かx86/x64など実行環境を見分けてそれぞれ用に1ファイル化が行われる(ただしx86とx64をまたいで1ファイル化は行われない)。

今回の例

const express = require('express');
const app = express();
app.use(express.static('./'));
app.listen(80, ()=> {
  console.log('Express Server 01');
});

さて,普通がserv.jsにrequireで指定したモジュールもひとまとめにされるのだが,少し癖があって必要なモジュールが抜けることがある。
できれば
npm init -y
でpackage.jsonを用意して,
npm install -D xxxx
でそのアプリケーションの実行に必要なバージョンのモジュールを固めておくとよい(と思う)。
ただし,ほかのアプリケーション用のpackage.jsonのあるフォルダでpkgコマンドを実行すると失敗する可能性がある。

ちなみに上のコマンドnode10-win64ならserv-win.exeができた。
(2018.10.04追加: 一応,上例ではこの操作でserv-linux/serv-macosも出来ている。もし,ターゲットが固定されていれば--target=node10-win-x64を指定してほしい。pure javascriptでないものが混ざるなどserv-linuxやserv-macosが作れない事情があると失敗するらしい)
うまくできた仕組みである。

上の例ではどこが./かは注意。
ショートカットを作って起動する場合には作業フォルダの指令を忘れないでおかないと意図しないフォルダが露出してしまう

 

≫ 続きを読む

2018/09/29 コンピュータ   TakeMe