タグ『 UWP(C++/CX) 』

≒ jawiki/latest 20170501/ のページ数の件>2162494

いやー。更新が3カ月空いちゃった。約2.5万レコード増加。ここ最近の増加ペースからするとちょっと少な目かな。

この3カ月で世の中には色々変化があったけど、俺は相変わらずUWPアプリで四苦八苦。次のアプリはほぼ完成形に行きついたんだけど、バグ取の辛さでもうアプリ断念しちゃいそう。アプリの設計というか、ロジック以外の部分で躓くんだよね。で、ググっても情報なし。

最近はもうオカルトというか、陰謀論に取りつかれてる。半分マジで。
というのはGoogleの作為が入ってるんじゃないかと、この情報の少なさは。
まぁBingで探しても情報少ないんだから(でもGoogle検索よりはほんの少しマシ)、オカルトなんだけどね。
て言うてたらBuild2017についてのMicroSoftからのお知らせメールがGmailの迷惑メールフォルダに入る。
例の「最近受け取った迷惑メールに酷似しています」云々のメッセージとともに。
やっぱり何かあるのかなw

≒ 【未解決】UWP(C++/CX)アプリでのダブルタップイベント不具合

結局解決できなかったので後日改めてのための覚え書き。ヘッダファイルとか諸々は省略&コード内容も大分簡略化。
(一応動くように出来たので最後に追記しました。でもおまじないみたいな実装で、とても「解決」と言えるレベルのものではないのでタイトルはそのままw)
[code language=”cpp”]
void MyApp::MainPage::OnDoubleTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs^ e){
e->Handled = true;

// Windows::Foundation::Collections::IVector<MyClass^>^ classesがあって、それを操作する処理
//各MyClassはMainPage.xaml内でGridやその中のRelativePanel、TextBlockとx:Bindで繋げてある。
change_classes();

Update_bindings();
}

void MyApp::MainPage::Update_bindings()
{
try
{
if (this != nullptr &&this->Bindings != nullptr) {
this->Bindings->Update();
}

}
catch (Platform::Exception^ e)
{
OutPrintln(e->Message, true);
}
}

void MyApp::MainPage::OutPrintln(Platform::String ^ s, Platform::Boolean flg)
{
Platform::String^ tmp = s;
if (flg) {
tmp = tmp + L"\r\n";
}
OutputDebugString(tmp->Data());
}
[/code]
で、ダブルタップすると落ちる。
「ハンドルされない例外が 0x023CE76B (Windows.UI.Xaml.dll) で発生しました(MyApp.exe 内): 0xC000041D: ユーザー コールバック中に未処理の例外が発生しました。。 」
「。」が二つあるのも気になるけど、とにかく落ちる。
メッセージが「例外がスローされました:読み取りアクセス違反。**this** が nullptr でした。 が発生しました」って時もあって、UWPが未だに良く分かってない俺にはどうしようもない。
IVectorへのアクセスミスかなと思ってそこ見直しても違いは無い。何が原因か突き止めるのに一日。
[code language=”cpp”]
void MyApp::MainPage::OnDoubleTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs^ e){
e->Handled = true;
change_classes();

//Update_bindings();
}
[/code]
コメントアウトすると大丈夫。更に変だと思ったので
[code language=”cpp”]
void MyApp::MainPage::OnDoubleTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs^ e){
e->Handled = true;
change_classes();

OutPrintln("AAA", true);
Update_bindings();
OutPrintln("CCC", true);
}

void MyApp::MainPage::Update_bindings()
{
OutPrintln("BBB", true);
try
{
if (this != nullptr &&this->Bindings != nullptr) {
this->Bindings->Update();
}

}
catch (Platform::Exception^ e)
{
OutPrintln(e->Message, true);
}
}
[/code]
として走らせると、
[code language=”bash”]
AAA
BBB
CCC
[/code]
と出力してから落ちる。
ダブルタップで発生する処理は、ドラッグ&ドロップでも発生する処理なので、少し手直ししてメソッドを共通化してもダブルタップだけ落ちる。
そもそも落ちるときにソースの表示がされないで「automaticdraghelper.cppが見つかりません」と出る。なお「automaticdraghelper」でググると珍しく「automaticdraghelper に一致する情報は見つかりませんでした。」とでる。ほんとにUWPは情報少ない。
「呼び出し履歴」ってウィンドウを見ると全然俺のコードとは関係ないところで落ちてるようだし、今回はあきらめてこのタップイベント拾うのやめるか(他の部分でのダブルタップ実装は何の問題もない)と考えて、コードを削る前最後に単純にOnDoubleTappedのまま(DoubleTappedRoutedEventArgsのまま)、シングルタップイベントに付け替えたらちゃんと動く。あきれたーw 要はUWPのダブルタップイベントの不具合は俺には突き止められないことが今回は分かった。
その後はシングルタップイベントハンドラを工夫して「疑似ダブルタップ」みたいなこともやろうとして、Windows::UI::Xaml::DispatcherTimerとか仕込んで、いざ動作確認!って走らせたらなんか変。すごく長い間隔の2回タップは当然「2回のシングルタップ」として認識して、ちょっと早めの(いわゆるダブルタップより微妙に長い間隔の)2回タップを「ダブルタップ」として認識する。そしてすごく早い2回タップ(いわゆるダブルタップ)は全部「1回のシングルタップ」になっちゃう。何で? 要するにシングルタップイベントの発生にはインターバルが必要なのか。なるほどねー。というオチも付いたということで、今回は以上。

[20時追記]
MSのフォーラムに情報あり。UWPアプリにはダブルタップで処理が2回走ってエラーになる場合があるらしい。この例とは違うんだけど、同じダブルタップということで処理の途中にインターバル入れてみる。
[code language=”cpp”]
//我ながらページのコンストラクタでタイマーの設定やるのもどうかと思う。定石はOnNavigatedToでやるみたい。
MainPage::MainPage()
{
InitializeComponent();
mTimer = ref new Windows::UI::Xaml::DispatcherTimer();
TimeSpan span;
span.Duration = (1LL * 1000000000) / 1000;//1/10秒
mTimer->Interval = span;
mTimer->Tick += ref new Windows::Foundation::EventHandler<Platform::Object ^>(this, &MyApp::MainPage::mTimer_OnTick);
}

void MyApp::MainPage::OnDoubleTapped(Platform::Object^ sender, Windows::UI::Xaml::Input::DoubleTappedRoutedEventArgs^ e){
e->Handled = true;
mTimer->Start();
}

void MyApp::MainPage::mTimer_OnTick(Platform::Object ^sender, Platform::Object ^args)
{
mTimer->Stop();
change_classes();
Update_bindings();
}
[/code]
ダブルタップされてから1/10秒後に処理をするようにしただけ。これで落ちなくなった。なんか馬鹿々々しいな。今度こそ以上。

≒ jawiki/latest 20170220/ のページ数の件>2143336

また5000ちょっとレコード増加。Wikipediaさんは相変わらず順調。

俺のほうもイマイチ優れない体調除けば順調。でもコーディングの進捗は牛歩。ほんとC++/CXの情報の少なさはコピペプログラマには辛すぎる。
面白いのはstackoverflowやMSのフォーラムでもUWP関連のドキュメントの整備具合はあんまり評判が良くないように見受けられること。
やっぱり思うことは一緒だよなー。サンプル通り打ち込んでも動かないと何を信じればいいのかわからなくなっちゃう。
先日もAPIドキュメントに例として載ってたコードを打ち込んだ結果、
[code language=”cpp”]
void OnDrop(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
Platform::String^ aaa = safe_cast<Platform::String^> (e->Data->GetView()->Properties->Lookup("aaa"));
OutputDebugString((aaa + L"\r\n")->Data());
}
[/code]
落ちる。例そのまま、何も余計なことしていないのに落ちる。なおその例の載ってたドキュメントがどこだったかは失念。
というかドキュメントの更新頻度はすごく早いので2~3日前の状況と違うことがよくある。頑張ってくださってるのは間違いない。
で、数時間試行錯誤して結局サンプルを読むと違う書き方してるのでそれに倣ってみる。
[code language=”cpp”]
void OnDrop(Platform::Object^ sender, Windows::UI::Xaml::DragEventArgs^ e)
{
Platform::String^ aaa = safe_cast<Platform::String^> (e->DataView->Properties->Lookup("aaa"));
OutputDebugString((aaa + L"\r\n")->Data());
}
[/code]
問題なく動く。あの例は何だったんだということがあった。うーん。Javaで書いてる(コピペしてる)時と比べると一手間多い感じ。
まぁ俺のコーディング能力の無さが一番でかいんだけどね。