Files
hakorune/examples/test_icon_extraction.rs
Moe Charm e7f6666917 🎨 feat: EguiBox GUI開発基盤完成 + パーサー無限ループバグ修正
## 🚀 主要機能追加
### EguiBox - GUI開発基盤
- Windows版GUIメモ帳アプリ (simple_notepad.rs, nyash_notepad_jp.rs)
- 日本語フォント対応 (NotoSansJP-VariableFont_wght.ttf)
- BMPアイコン表示システム (c_drive_icon.bmp)
- Windowsエクスプローラー風アプリ (nyash_explorer.rs)
- アイコン抽出システム (test_icon_extraction.rs)

### ビジュアルプログラミング準備
- NyashFlow プロジェクト設計完成 (NYASHFLOW_PROJECT_HANDOVER.md)
- ビジュアルノードプロトタイプ基盤
- WebAssembly対応準備

## 🔧 重大バグ修正
### パーサー無限ループ問題 (3引数メソッド呼び出し)
- 原因: メソッドパラメータ解析ループの予約語処理不備
- 修正: src/parser/mod.rs - 非IDENTIFIERトークンのエラーハンドリング追加
- 効果: "from"等の予約語で適切なエラー報告、ハング→瞬時エラー

### MapBoxハング問題調査
- MapBox+3引数メソッド呼び出し組み合わせ問題特定
- バグレポート作成 (MAPBOX_HANG_BUG_REPORT.md)
- 事前評価vs必要時評価の設計問題明確化

## 🧹 コード品質向上
- box_methods.rs を8モジュールに機能分離
- 一時デバッグコード全削除 (eprintln\!, unsafe等)
- 構文チェック通過確認済み

## 📝 ドキュメント整備
- CLAUDE.md にGUI開発セクション追加
- Gemini/ChatGPT先生相談ログ保存 (sessions/)
- 段階的デバッグ手法確立

## 🎯 次の目標
- must_advance\!マクロ実装 (無限ループ早期検出)
- コマンド引数でデバッグ制御 (--debug-fuel)
- MapBox問題の根本修正

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-10 07:54:03 +09:00

137 lines
5.4 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Windows Icon Extraction Test
// アイコンを実際に取得してICOファイルとして保存するテスト
#[cfg(windows)]
use windows::{
core::*,
Win32::{
Storage::FileSystem::*,
UI::Shell::*,
UI::WindowsAndMessaging::*,
Graphics::Gdi::*,
},
};
fn main() {
#[cfg(windows)]
unsafe {
println!("Windows Icon Extraction Test");
// C:ドライブのアイコンを取得
let drive_path = "C:\\";
let drive_path_wide: Vec<u16> = drive_path.encode_utf16().chain(std::iter::once(0)).collect();
let mut shfi = SHFILEINFOW::default();
let result = SHGetFileInfoW(
PCWSTR::from_raw(drive_path_wide.as_ptr()),
FILE_ATTRIBUTE_NORMAL,
Some(&mut shfi),
std::mem::size_of::<SHFILEINFOW>() as u32,
SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES,
);
println!("SHGetFileInfoW result: {}", result);
if result != 0 && !shfi.hIcon.is_invalid() {
println!("Icon handle obtained!");
// アイコン情報を取得
let mut icon_info = ICONINFO::default();
if GetIconInfo(shfi.hIcon, &mut icon_info).is_ok() {
println!("GetIconInfo success!");
println!("fIcon: {}", icon_info.fIcon.as_bool());
// ビットマップ情報を取得
if !icon_info.hbmColor.is_invalid() {
println!("Color bitmap handle obtained!");
// ビットマップ情報を取得
let mut bitmap = BITMAP::default();
let size = GetObjectW(
icon_info.hbmColor.into(),
std::mem::size_of::<BITMAP>() as i32,
Some(&mut bitmap as *mut _ as *mut _)
);
if size > 0 {
println!("Bitmap info:");
println!(" Width: {}", bitmap.bmWidth);
println!(" Height: {}", bitmap.bmHeight);
println!(" Bits per pixel: {}", bitmap.bmBitsPixel);
println!(" Planes: {}", bitmap.bmPlanes);
// ピクセルデータを取得
let pixel_count = (bitmap.bmWidth * bitmap.bmHeight) as usize;
let bytes_per_pixel = (bitmap.bmBitsPixel / 8) as usize;
let mut pixels = vec![0u8; pixel_count * bytes_per_pixel];
let copied = GetBitmapBits(
icon_info.hbmColor,
pixels.len() as i32,
pixels.as_mut_ptr() as *mut _
);
println!("Copied {} bytes of pixel data", copied);
// 簡易的にBMPファイルとして保存
if copied > 0 {
save_as_bmp("c_drive_icon.bmp", &pixels, bitmap.bmWidth, bitmap.bmHeight, bitmap.bmBitsPixel);
println!("Saved as c_drive_icon.bmp");
}
}
// ビットマップを削除
let _ = DeleteObject(icon_info.hbmColor.into());
}
if !icon_info.hbmMask.is_invalid() {
println!("Mask bitmap handle obtained!");
let _ = DeleteObject(icon_info.hbmMask.into());
}
}
// アイコンを破棄
let _ = DestroyIcon(shfi.hIcon);
} else {
println!("Failed to get icon");
}
}
#[cfg(not(windows))]
println!("This test only works on Windows");
}
#[cfg(windows)]
fn save_as_bmp(filename: &str, pixels: &[u8], width: i32, height: i32, bits_per_pixel: u16) {
use std::fs::File;
use std::io::Write;
// 簡易BMPヘッダー実際の実装はもっと複雑
let file_size = 54 + pixels.len() as u32;
let mut file = File::create(filename).unwrap();
// BMPファイルヘッダー
file.write_all(b"BM").unwrap(); // マジックナンバー
file.write_all(&file_size.to_le_bytes()).unwrap();
file.write_all(&0u32.to_le_bytes()).unwrap(); // 予約
file.write_all(&54u32.to_le_bytes()).unwrap(); // データオフセット
// BMPインフォヘッダー
file.write_all(&40u32.to_le_bytes()).unwrap(); // ヘッダーサイズ
file.write_all(&width.to_le_bytes()).unwrap();
file.write_all(&height.to_le_bytes()).unwrap();
file.write_all(&1u16.to_le_bytes()).unwrap(); // プレーン数
file.write_all(&bits_per_pixel.to_le_bytes()).unwrap();
file.write_all(&0u32.to_le_bytes()).unwrap(); // 圧縮なし
file.write_all(&(pixels.len() as u32).to_le_bytes()).unwrap();
file.write_all(&0i32.to_le_bytes()).unwrap(); // X解像度
file.write_all(&0i32.to_le_bytes()).unwrap(); // Y解像度
file.write_all(&0u32.to_le_bytes()).unwrap(); // カラーテーブル数
file.write_all(&0u32.to_le_bytes()).unwrap(); // 重要な色数
// ピクセルデータ
file.write_all(pixels).unwrap();
println!("BMP file saved: {}", filename);
}