microSD カードのビットマップ・ファイルのビュアー.画像の最大値 縦:272ピクセル,横:480ピクセル. Bitmap file viewer for microSD card. Maximum size Vertical: 272 pixels, Horizontal: 480.

Dependencies:   SDFileSystem_Warning_Fixed F746_GUI

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Tue Oct 23 11:51:47 2018 +0000
Parent:
0:f62ffd3644bf
Commit message:
2

Changed in this revision

BitmapReader.cpp Show diff for this revision Revisions of this file
BitmapReader.hpp Show diff for this revision Revisions of this file
FileSelectorBmp.cpp Show diff for this revision Revisions of this file
FileSelectorBmp.hpp Show diff for this revision Revisions of this file
MyFiles/BitmapReader.cpp Show annotated file Show diff for this revision Revisions of this file
MyFiles/BitmapReader.hpp Show annotated file Show diff for this revision Revisions of this file
MyFiles/FileSelectorBmp.cpp Show annotated file Show diff for this revision Revisions of this file
MyFiles/FileSelectorBmp.hpp Show annotated file Show diff for this revision Revisions of this file
MyFiles/ReadAndDisplay.hpp Show annotated file Show diff for this revision Revisions of this file
ReadAndDisplay.hpp Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/BitmapReader.cpp	Sun Oct 21 11:29:47 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-//-----------------------------------------------------------
-// SD_BitmapReader クラス(ヘッダ)
-//      SD カードの *.bmp ファイルの内容を読み出す
-//      ファイルの画素数の最大値:480×272 ピクセル
-//
-//  2018/10/20, Copyright (c) 2018 MIKAMI, Naoki
-//-----------------------------------------------------------
-
-#include "BitmapReader.hpp"
-
-namespace Mikami
-{
-    SD_BitmapReader::~SD_BitmapReader()
-    {
-        sd_->unmount();
-        delete sd_;
-    }
-
-    void SD_BitmapReader::Open(const string fileName)
-    {
-        string name = (string)"/" + STR_ + "/" + fileName;
-        fp_ = fopen(name.c_str(), "rb");
-        if (fp_ == NULL) ErrorMsg("open error!!");
-    }
-
-    // 条件に合うビットマップ・ファイルかどうか調べる
-    //      戻り値:条件に合うビットマップ・ファイルの場合 true
-    bool SD_BitmapReader::IsAllowed()
-    {
-        uint8_t data[54];   // Windows のピットマップ・ファイルのヘッダは 54 ビットに固定
-        fread(data, 1, 54, fp_);    // 54 バイト分を読み込む
-
-        // ファイルタイプを調べる
-        if ((data[0] != 'B') || (data[1] != 'M')) return false;
-
-        // 画像の幅が許される最大のピクセル数を超えていないか調べる
-        if (*(uint32_t *)(data+18) > maxWidth_) return false;
-
-        // 画像の高さが許される最大のピクセル数を超えていないか調べる
-        if (*(uint32_t *)(data+22) > maxHeight_) return false;
-
-        return true;
-    }
-}
--- a/BitmapReader.hpp	Sun Oct 21 11:29:47 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-//-----------------------------------------------------------
-// SD_BitmapReader クラス(ヘッダ)
-//      SD カードの *.bmp ファイルの内容を読み出す
-//      ファイルの画素数:480×272 ピクセル
-//
-//  2018/10/20, Copyright (c) 2018 MIKAMI, Naoki
-//-----------------------------------------------------------
-
-#ifndef SD_BITMAP_READER_HPP
-#define SD_BITMAP_READER_HPP
-
-#include "mbed.h"
-#include "SDFileSystem.h"
-#include "BlinkLabel.hpp"
-#include "Array.hpp"
-#include <string>
-
-namespace Mikami
-{
-    class SD_BitmapReader
-    {
-    public:
-        SD_BitmapReader(uint16_t maxWidth, uint16_t maxHeight)
-            : STR_("sd"), sd_(new SDFileSystem(STR_.c_str())),
-              maxWidth_(maxWidth), maxHeight_(maxHeight)
-        { sd_->mount(); }
-
-        virtual ~SD_BitmapReader();
-
-        void Open(const string fileName);
-        
-        void Close() { fclose(fp_); }
-
-        // 条件に合うビットマップ・ファイルかどうか調べる
-        bool IsAllowed();
-
-        // ファイルの読み出し
-        //      size    読み出すデータのバイト数
-        size_t ReadFile(uint8_t data[], size_t size)
-        { return fread(data, 1, size, fp_); }
-        
-        // 画像の高さの取得
-        uint32_t  GetHeight(uint8_t *bmp)
-        { return *(uint32_t *)(bmp+22); }
-
-        // 画像の幅の取得
-        uint32_t  GetWidth(uint8_t *bmp)
-        { return *(uint32_t *)(bmp+18); }
-
-        // 画像のサイズの取得
-        uint32_t  GetSize(uint8_t *bmp)
-        { return *(uint32_t *)(bmp+34); }
-
-        // 画像の高さの設定
-        void SetHeight(uint8_t *bmp, uint32_t height)
-        { *(uint32_t *)(bmp+22) = height; }
-
-        // 画像の幅の設定
-        void SetWidth(uint8_t *bmp, uint32_t width)
-        { *(uint32_t *)(bmp+18) = width; }
-
-        // 画像のサイズの設定
-        void SetSize(uint8_t *bmp, uint32_t size)
-        { *(uint32_t *)(bmp+34) = size; }
-
-    private:
-        const string STR_;
-
-        SDFileSystem *sd_;
-        FILE *fp_;
-        
-        uint16_t maxWidth_;
-        uint16_t maxHeight_;
-
-        void ErrorMsg(char msg[])
-        {   BlinkLabel errLabel(240, 100, msg, Label::CENTER); }
-    };
-}
-#endif  // SD_BITMAP_READER_HPP
\ No newline at end of file
--- a/FileSelectorBmp.cpp	Sun Oct 21 11:29:47 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-//--------------------------------------------------------------
-//  FileSelector class
-//      SD カード内の *.bmp ファイル名の一覧を表示し,ファイルを選択する
-//
-//  2018/10/18, Copyright (c) 2018 MIKAMI, Naoki
-//--------------------------------------------------------------
-
-#include "FileSelectorBmp.hpp"
-
-namespace Mikami
-{
-    FileSelector::FileSelector(uint8_t x0, uint8_t y0, int maxFiles,
-                               int maxNameLength, SD_BitmapReader &reader)
-        : X_(x0), Y_(y0),
-          MAX_FILES_(maxFiles), MAX_NAME_LENGTH_(maxNameLength),
-          fileNames_(maxFiles), fileNameLabels_(MAX_LIST_PAGE_),
-          next_(50, 235, 64, 36, 2, (string[]){"<", ">"}, 10, 0, 2, -1, Font24),
-          pageLabel_(210, 250, Label::LEFT, Font16),
-          lcd_(GuiBase::GetLcd()), sdReader_(reader), page_(1),
-          nOld_(-1), kOld_(-1)
-    {
-        Array<string> nonString(MAX_LIST_PAGE_, "");
-        rect_ = new ButtonGroup(X_, Y_, W_H_, W_H_, MAX_LIST_PAGE_,
-                                nonString, 0, V_L_-W_H_, 1,
-                                -1, Font12, 0, GuiBase::ENUM_BACK,
-                                BASE_COLOR_, TOUCHED_COLOR_);
-        rect_->EraseAll();
-        next_.EraseAll();
-
-        // Label を生成
-        for (int n=0; n<MAX_LIST_PAGE_; n++)
-            fileNameLabels_[n] = new Label(X_+30, Y_+5+V_L_*n, "",
-                                           Label::LEFT, Font16, BASE_COLOR_);
-    }
-
-    FileSelector::~FileSelector()
-    {   
-        delete rect_;
-        for (int n=0; n<MAX_LIST_PAGE_; n++) delete fileNameLabels_[n];
-    }
-
-    // ファイルの一覧表を作る.BMP ファイルが存在しない場合は false を返す
-    bool FileSelector::CreateTable()
-    {
-        DIR* dp = opendir("/sd");
-        fileCount_ = 0; 
-        if (dp != NULL)
-        {
-            dirent* entry;
-            for (int n=0; n<256; n++)
-            {
-                entry = readdir(dp);
-                if (entry == NULL) break;
-
-                string strName = entry->d_name;
-                if ( (strName.find(".bmp") != string::npos) ||
-                     (strName.find(".BMP") != string::npos) )
-                {
-                    sdReader_.Open(strName);        // ファイルオープン
-
-                    // 不適切なファイルは除外
-                    if (sdReader_.IsAllowed())
-                        fileNames_[fileCount_++] = strName;
-                    sdReader_.Close();
-                }
-                if (fileCount_ >= MAX_FILES_) break;
-            }
-            closedir(dp);
-        }
-        else
-            return false;                   // SD カードが装着されていない場合
-        if (fileCount_ == 0) return false;  // 該当する BMP ファイルが存在しない場合
-
-        div_t m = div(fileCount_, MAX_LIST_PAGE_);
-        maxPage_ = (m.rem == 0) ? m.quot : m.quot+1;
-        return true;                        // 該当する BMP ファイルが存在する場合
-    }
-
-    // ファイルを選択する
-    bool FileSelector::Select(string &fileName)
-    {
-        int m;
-        if (next_.GetTouchedNumber(m))
-        {
-            if (m==0) page_--;
-            else      page_++;
-            DisplayFileList(false);
-            nOld_ = -1;
-            wait_ms(300);
-        }
-        
-        int n;
-        if (rect_->GetTouchedNumber(n))
-        {
-            int k = (page_ - 1)*MAX_LIST_PAGE_ + n;
-            fileNameLabels_[n]->Draw(GetFileNameNoExt(k),
-                                     TOUCHED_COLOR_);
-            fileName = fileNames_[k];
-            // 同じページで以前に選択されているファイル名の色を戻す
-            if (nOld_ != -1)
-                fileNameLabels_[nOld_]->Draw(GetFileNameNoExt(kOld_),
-                                             BASE_COLOR_);
-            if (page_ == maxPage_)      // 最後のページで余分な四角形を消去
-                for (int j=fileCount_ % MAX_LIST_PAGE_ + 1;
-                     j < MAX_LIST_PAGE_; j++) rect_->Erase(j);
-            nOld_ = n;
-            kOld_ = k;
-            return true;
-        }
-        else
-            return false;
-    }
-
-    // ファイルの一覧の表示
-    void FileSelector::DisplayFileList(bool sortEnable)
-    {
-        if (sortEnable)
-            std::sort((string *)fileNames_,
-                      (string *)fileNames_+fileCount_); 
-        
-        Erase(0, 0, 480, 272);
-
-        div_t m = div(fileCount_, MAX_LIST_PAGE_);
-        int count = (m.quot >= page_) ? MAX_LIST_PAGE_ : m.rem;
-        for (int n=0; n<count; n++) rect_->Draw(n);
-        for (int n=0; n<count; n++)
-            fileNameLabels_[n]->Draw(GetFileNameNoExt(n+(page_-1)*MAX_LIST_PAGE_));
-
-        // 前のページ,次のページの選択ボタンなどを表示する
-        next_.InactivateAll();
-        if (page_ > 1) next_.Activate(0);           // "<" 有効
-        if (page_ < maxPage_) next_.Activate(1);    // ">" 有効
-        char page[6];
-        sprintf(page, "%d/%d", page_, maxPage_);
-        pageLabel_.Draw(page);
-    }
-
-    // ファイルの一覧の消去
-    void FileSelector::Erase(uint16_t x, uint16_t y, uint16_t width,
-                             uint16_t height, uint32_t color)
-    {
-        lcd_.SetTextColor(color);
-        lcd_.FillRect(x, y, width, height);
-    }
-
-    // 拡張子を削除したファイル名を取得
-    string FileSelector::GetFileNameNoExt(int n)
-    {
-        string name = fileNames_[n];
-        int k = name.rfind(".");
-        if (k != string::npos)
-            return name.erase(k);
-        else
-            return name;
-    }
-}
--- a/FileSelectorBmp.hpp	Sun Oct 21 11:29:47 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-//--------------------------------------------------------------
-//  FileSelector class ---- Header ----
-//      SD カード内の *.bmp ファイル名の一覧を表示し,ファイルを選択する
-//
-//  2018/10/18, Copyright (c) 2018 MIKAMI, Naoki
-//--------------------------------------------------------------
-
-#ifndef FILE_SELECTOR_HPP
-#define FILE_SELECTOR_HPP
-
-#include "F746_GUI.hpp"
-#include "BitmapReader.hpp"
-#include <algorithm>    // sort() で使用
-#include <string>
-
-namespace Mikami
-{
-    class FileSelector
-    {
-    public:
-        FileSelector(uint8_t x0, uint8_t y0, int maxFiles,
-                     int maxNameLength, SD_BitmapReader &reader);
-
-        virtual ~FileSelector();
-        
-        // ファイルの一覧表を作る.BMP ファイルが存在しない場合は false を返す
-        bool CreateTable();
-
-        // ファイルを選択する
-        bool Select(string &fileName);
-
-        // ファイルの一覧の表示
-        void DisplayFileList(bool sortEnable = true);
-
-        // ファイルの一覧の消去
-        void Erase(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
-                   uint32_t color = GuiBase::ENUM_BACK);
-
-    private:
-        static const int MAX_LIST_PAGE_ = 6;  // 1ページに表示するファイル数の最大値
-        static const uint8_t W_H_ = 24;
-        static const uint8_t V_L_ = 36;
-        static const uint32_t BASE_COLOR_ = 0xFF80FFA0;
-        static const uint32_t TOUCHED_COLOR_ = 0xFF80FFFF;
-        const uint8_t X_, Y_;
-        const int MAX_FILES_;
-        const int MAX_NAME_LENGTH_;
-        
-        Array<string> fileNames_;
-        Array<Label *> fileNameLabels_;
-        ButtonGroup *rect_;
-        ButtonGroup next_;
-        Label pageLabel_;
-        LCD_DISCO_F746NG &lcd_;
-        SD_BitmapReader &sdReader_;
-        int page_;      // 現在のページ,最初のページは 1
-        int nOld_;      // ページ内で以前選択したファイルのインデックス
-        int kOld_;      // 以前選択したファイルのインデックス
-        int maxPage_;
-        int fileCount_;
-
-        // 拡張子を削除したファイル名を取得
-        string GetFileNameNoExt(int n);
-
-        // コピー・コンストラクタとオブジェクトの代入演算子は使用禁止
-        FileSelector(const FileSelector&);
-        FileSelector& operator=(const FileSelector&);
-    };
-}
-#endif  // FILE_SELECTOR_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyFiles/BitmapReader.cpp	Tue Oct 23 11:51:47 2018 +0000
@@ -0,0 +1,56 @@
+//-----------------------------------------------------------
+// SD_BitmapReader クラス(ヘッダ)
+//      SD カードの *.bmp ファイルの内容を読み出す
+//      ファイルの画素数の最大値:480×272 ピクセル
+//      だだし,ファイル名が日本語のものが除く
+//
+//  2018/10/23, Copyright (c) 2018 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "BitmapReader.hpp"
+
+namespace Mikami
+{
+    SD_BitmapReader::~SD_BitmapReader()
+    {
+        sd_->unmount();
+        delete sd_;
+    }
+
+    bool SD_BitmapReader::Open(const string fileName)
+    {
+        // シフト JIS のコードがあれば false を返す
+        for (int n=0; n<fileName.size(); n++)
+        {
+            uint8_t c = fileName[n];
+            if (((c>=0x81) && (c<=0x9f)) || ((c>=0xe0) && (c<=0xfc)))
+                return false;
+        }
+
+        string name = (string)"/" + STR_ + "/" + fileName;
+        fp_ = fopen(name.c_str(), "rb");
+        if (fp_ == NULL) ErrorMsg("open error!!");
+        
+        return true;
+    }
+
+    // 条件に合うビットマップ・ファイルかどうか調べる
+    //      戻り値:条件に合うビットマップ・ファイルの場合 true
+    bool SD_BitmapReader::IsAllowed()
+    {
+        uint8_t data[54];   // Windows のピットマップ・ファイルのヘッダは 54 ビットに固定
+        fread(data, 1, 54, fp_);    // 54 バイト分を読み込む
+
+        // ファイルタイプを調べる
+        if ((data[0] != 'B') || (data[1] != 'M')) return false;
+
+        // 画像の幅が許される最大のピクセル数を超えていないか調べる
+        if (*(uint32_t *)(data+18) > maxWidth_) return false;
+
+        // 画像の高さが許される最大のピクセル数を超えていないか調べる
+        if (*(uint32_t *)(data+22) > maxHeight_) return false;
+
+        return true;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyFiles/BitmapReader.hpp	Tue Oct 23 11:51:47 2018 +0000
@@ -0,0 +1,80 @@
+//-----------------------------------------------------------
+// SD_BitmapReader クラス(ヘッダ)
+//      SD カードの *.bmp ファイルの内容を読み出す
+//      ファイルの画素数:480×272 ピクセル
+//      だだし,ファイル名が日本語のものが除く
+//
+//  2018/10/23, Copyright (c) 2018 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef SD_BITMAP_READER_HPP
+#define SD_BITMAP_READER_HPP
+
+#include "mbed.h"
+#include "SDFileSystem.h"
+#include "BlinkLabel.hpp"
+#include "Array.hpp"
+#include <string>
+
+namespace Mikami
+{
+    class SD_BitmapReader
+    {
+    public:
+        SD_BitmapReader(uint16_t maxWidth, uint16_t maxHeight)
+            : STR_("sd"), sd_(new SDFileSystem(STR_.c_str())),
+              maxWidth_(maxWidth), maxHeight_(maxHeight)
+        { sd_->mount(); }
+
+        virtual ~SD_BitmapReader();
+
+        bool Open(const string fileName);
+        
+        void Close() { fclose(fp_); }
+
+        // 条件に合うビットマップ・ファイルかどうか調べる
+        bool IsAllowed();
+
+        // ファイルの読み出し
+        //      size    読み出すデータのバイト数
+        size_t ReadFile(uint8_t data[], size_t size)
+        { return fread(data, 1, size, fp_); }
+        
+        // 画像の高さの取得
+        uint32_t  GetHeight(uint8_t *bmp)
+        { return *(uint32_t *)(bmp+22); }
+
+        // 画像の幅の取得
+        uint32_t  GetWidth(uint8_t *bmp)
+        { return *(uint32_t *)(bmp+18); }
+
+        // 画像のサイズの取得
+        uint32_t  GetSize(uint8_t *bmp)
+        { return *(uint32_t *)(bmp+34); }
+
+        // 画像の高さの設定
+        void SetHeight(uint8_t *bmp, uint32_t height)
+        { *(uint32_t *)(bmp+22) = height; }
+
+        // 画像の幅の設定
+        void SetWidth(uint8_t *bmp, uint32_t width)
+        { *(uint32_t *)(bmp+18) = width; }
+
+        // 画像のサイズの設定
+        void SetSize(uint8_t *bmp, uint32_t size)
+        { *(uint32_t *)(bmp+34) = size; }
+
+    private:
+        const string STR_;
+
+        SDFileSystem *sd_;
+        FILE *fp_;
+        
+        uint16_t maxWidth_;
+        uint16_t maxHeight_;
+
+        void ErrorMsg(char msg[])
+        {   BlinkLabel errLabel(240, 100, msg, Label::CENTER); }
+    };
+}
+#endif  // SD_BITMAP_READER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyFiles/FileSelectorBmp.cpp	Tue Oct 23 11:51:47 2018 +0000
@@ -0,0 +1,159 @@
+//--------------------------------------------------------------
+//  FileSelector class
+//      SD カード内の *.bmp ファイル名の一覧を表示し,ファイルを選択する
+//      だだし,日本語のファイル名は除く
+//
+//  2018/10/23, Copyright (c) 2018 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#include "FileSelectorBmp.hpp"
+
+namespace Mikami
+{
+    FileSelector::FileSelector(uint8_t x0, uint8_t y0, int maxFiles,
+                               int maxNameLength, SD_BitmapReader &reader)
+        : X_(x0), Y_(y0),
+          MAX_FILES_(maxFiles), MAX_NAME_LENGTH_(maxNameLength),
+          fileNames_(maxFiles), fileNameLabels_(MAX_LIST_PAGE_),
+          next_(50, 235, 64, 36, 2, (string[]){"<", ">"}, 10, 0, 2, -1, Font24),
+          pageLabel_(210, 250, Label::LEFT, Font16),
+          lcd_(GuiBase::GetLcd()), sdReader_(reader), page_(1),
+          nOld_(-1), kOld_(-1)
+    {
+        Array<string> nonString(MAX_LIST_PAGE_, "");
+        rect_ = new ButtonGroup(X_, Y_, W_H_, W_H_, MAX_LIST_PAGE_,
+                                nonString, 0, V_L_-W_H_, 1,
+                                -1, Font12, 0, GuiBase::ENUM_BACK,
+                                BASE_COLOR_, TOUCHED_COLOR_);
+        rect_->EraseAll();
+        next_.EraseAll();
+
+        // Label を生成
+        for (int n=0; n<MAX_LIST_PAGE_; n++)
+            fileNameLabels_[n] = new Label(X_+30, Y_+5+V_L_*n, "",
+                                           Label::LEFT, Font16, BASE_COLOR_);
+    }
+
+    FileSelector::~FileSelector()
+    {   
+        delete rect_;
+        for (int n=0; n<MAX_LIST_PAGE_; n++) delete fileNameLabels_[n];
+    }
+
+    // ファイルの一覧表を作る.BMP ファイルが存在しない場合は false を返す
+    bool FileSelector::CreateTable()
+    {
+        DIR* dp = opendir("/sd");
+        fileCount_ = 0; 
+        if (dp != NULL)
+        {
+            dirent* entry;
+            for (int n=0; n<256; n++)
+            {
+                entry = readdir(dp);
+                if (entry == NULL) break;
+
+                string strName = entry->d_name;
+                if ( (strName.find(".bmp") != string::npos) ||
+                     (strName.find(".BMP") != string::npos) )
+                {
+                    if (sdReader_.Open(strName))        // ファイルのオープン
+                    {
+                        // 不適切なファイルは除外
+                        if (sdReader_.IsAllowed())
+                            fileNames_[fileCount_++] = strName;
+                        sdReader_.Close();
+                    }
+                }
+                if (fileCount_ >= MAX_FILES_) break;
+            }
+            closedir(dp);
+        }
+        else
+            return false;                   // SD カードが装着されていない場合
+        if (fileCount_ == 0) return false;  // 該当する BMP ファイルが存在しない場合
+
+        div_t m = div(fileCount_, MAX_LIST_PAGE_);
+        maxPage_ = (m.rem == 0) ? m.quot : m.quot+1;
+        return true;                        // 該当する BMP ファイルが存在する場合
+    }
+
+    // ファイルを選択する
+    bool FileSelector::Select(string &fileName)
+    {
+        int m;
+        if (next_.GetTouchedNumber(m))
+        {
+            if (m==0) page_--;
+            else      page_++;
+            DisplayFileList(false);
+            nOld_ = -1;
+            wait_ms(300);
+        }
+        
+        int n;
+        if (rect_->GetTouchedNumber(n))
+        {
+            int k = (page_ - 1)*MAX_LIST_PAGE_ + n;
+            fileNameLabels_[n]->Draw(GetFileNameNoExt(k),
+                                     TOUCHED_COLOR_);
+            fileName = fileNames_[k];
+            // 同じページで以前に選択されているファイル名の色を戻す
+            if (nOld_ != -1)
+                fileNameLabels_[nOld_]->Draw(GetFileNameNoExt(kOld_),
+                                             BASE_COLOR_);
+            if (page_ == maxPage_)      // 最後のページで余分な四角形を消去
+                for (int j=fileCount_ % MAX_LIST_PAGE_ + 1;
+                     j < MAX_LIST_PAGE_; j++) rect_->Erase(j);
+            nOld_ = n;
+            kOld_ = k;
+            return true;
+        }
+        else
+            return false;
+    }
+
+    // ファイルの一覧の表示
+    void FileSelector::DisplayFileList(bool sortEnable)
+    {
+        if (sortEnable)
+            std::sort((string *)fileNames_,
+                      (string *)fileNames_+fileCount_); 
+        
+        Erase(0, 0, 480, 272);
+
+        div_t m = div(fileCount_, MAX_LIST_PAGE_);
+        int count = (m.quot >= page_) ? MAX_LIST_PAGE_ : m.rem;
+        for (int n=0; n<count; n++) rect_->Draw(n);
+        for (int n=0; n<count; n++)
+            fileNameLabels_[n]->Draw(GetFileNameNoExt(n+(page_-1)*MAX_LIST_PAGE_));
+
+        // 前のページ,次のページの選択ボタンなどを表示する
+        next_.InactivateAll();
+        if (page_ > 1) next_.Activate(0);           // "<" 有効
+        if (page_ < maxPage_) next_.Activate(1);    // ">" 有効
+        char page[6];
+        sprintf(page, "%d/%d", page_, maxPage_);
+        pageLabel_.Draw(page);
+    }
+
+    // ファイルの一覧の消去
+    void FileSelector::Erase(uint16_t x, uint16_t y, uint16_t width,
+                             uint16_t height, uint32_t color)
+    {
+        lcd_.SetTextColor(color);
+        lcd_.FillRect(x, y, width, height);
+    }
+
+    // 拡張子を削除したファイル名を取得
+    string FileSelector::GetFileNameNoExt(int n)
+    {
+        string name = fileNames_[n];
+        int k = name.rfind(".");
+        if (k != string::npos)
+            return name.erase(k);
+        else
+            return name;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyFiles/FileSelectorBmp.hpp	Tue Oct 23 11:51:47 2018 +0000
@@ -0,0 +1,72 @@
+//--------------------------------------------------------------
+//  FileSelector class ---- Header ----
+//      SD カード内の *.bmp ファイル名の一覧を表示し,ファイルを選択する
+//      だだし,日本語のファイル名は除く
+//
+//  2018/10/23, Copyright (c) 2018 MIKAMI, Naoki
+//--------------------------------------------------------------
+
+#ifndef FILE_SELECTOR_HPP
+#define FILE_SELECTOR_HPP
+
+#include "F746_GUI.hpp"
+#include "BitmapReader.hpp"
+#include <algorithm>    // sort() で使用
+#include <string>
+
+namespace Mikami
+{
+    class FileSelector
+    {
+    public:
+        FileSelector(uint8_t x0, uint8_t y0, int maxFiles,
+                     int maxNameLength, SD_BitmapReader &reader);
+
+        virtual ~FileSelector();
+        
+        // ファイルの一覧表を作る.BMP ファイルが存在しない場合は false を返す
+        bool CreateTable();
+
+        // ファイルを選択する
+        bool Select(string &fileName);
+
+        // ファイルの一覧の表示
+        void DisplayFileList(bool sortEnable = true);
+
+        // ファイルの一覧の消去
+        void Erase(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
+                   uint32_t color = GuiBase::ENUM_BACK);
+
+    private:
+        static const int MAX_LIST_PAGE_ = 6;  // 1ページに表示するファイル数の最大値
+        static const uint8_t W_H_ = 24;
+        static const uint8_t V_L_ = 36;
+        static const uint32_t BASE_COLOR_ = 0xFF80FFA0;
+        static const uint32_t TOUCHED_COLOR_ = 0xFF80FFFF;
+        const uint8_t X_, Y_;
+        const int MAX_FILES_;
+        const int MAX_NAME_LENGTH_;
+        
+        Array<string> fileNames_;
+        Array<Label *> fileNameLabels_;
+        ButtonGroup *rect_;
+        ButtonGroup next_;
+        Label pageLabel_;
+        LCD_DISCO_F746NG &lcd_;
+        SD_BitmapReader &sdReader_;
+        int page_;      // 現在のページ,最初のページは 1
+        int nOld_;      // ページ内で以前選択したファイルのインデックス
+        int kOld_;      // 以前選択したファイルのインデックス
+        int maxPage_;
+        int fileCount_;
+
+        // 拡張子を削除したファイル名を取得
+        string GetFileNameNoExt(int n);
+
+        // コピー・コンストラクタとオブジェクトの代入演算子は使用禁止
+        FileSelector(const FileSelector&);
+        FileSelector& operator=(const FileSelector&);
+    };
+}
+#endif  // FILE_SELECTOR_HPP
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MyFiles/ReadAndDisplay.hpp	Tue Oct 23 11:51:47 2018 +0000
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------
+//  microSD のビットマップファイルを読み込み表示するグローバル関数
+//      縦方向に分割して読み込みと描画を行う
+//      F746_GUI は Rev.32 を使うこと
+//
+//  2018/10/21, Copyright (c) 2018 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "BitmapReader.hpp"
+
+using namespace Mikami;
+
+void ReadAndDraw(const string fileName, SD_BitmapReader &sdReader,
+                 uint8_t bmp[], uint32_t headerSize, int div)
+{
+    sdReader.Open(fileName);            // ファイルのオープン
+    sdReader.ReadFile(bmp, headerSize); // ヘッダの読み込み
+
+    uint32_t height = sdReader.GetHeight(bmp);  // 画像の高さ,単位:ピクセル
+    uint32_t h0 = height/div;                   // 分割した画像の高さ,単位:ピクセル
+    sdReader.SetHeight(bmp, h0);                // 画像の高さ設定,単位:ピクセル
+
+    uint8_t *ptr = (uint8_t *)(bmp+headerSize); // 画像データのポインタ
+    uint32_t size = sdReader.GetSize(bmp)/div;  // 一度で読込む画像データのサイズ計算,単位:バイト
+
+    // 縦方向に分割して読み込みと描画を行う
+    for (int n=0; n<div; n++) 
+    {
+        sdReader.ReadFile(ptr, size);           // 画像データの読み込み
+        GuiBase::GetLcd().DrawBitmap(0, (div-1-n)*h0, bmp);
+    }
+
+    sdReader.Close();                   // ファイルのクローズ
+}
--- a/ReadAndDisplay.hpp	Sun Oct 21 11:29:47 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-//-----------------------------------------------------------
-//  microSD のビットマップファイルを読み込み表示するグローバル関数
-//      縦方向に分割して読み込みと描画を行う
-//      F746_GUI は Rev.32 を使うこと
-//
-//  2018/10/21, Copyright (c) 2018 MIKAMI, Naoki
-//-----------------------------------------------------------
-
-#include "BitmapReader.hpp"
-
-using namespace Mikami;
-
-void ReadAndDraw(const string fileName, SD_BitmapReader &sdReader,
-                 uint8_t bmp[], uint32_t headerSize, int div)
-{
-    sdReader.Open(fileName);            // ファイルのオープン
-    sdReader.ReadFile(bmp, headerSize); // ヘッダの読み込み
-
-    uint32_t height = sdReader.GetHeight(bmp);  // 画像の高さ,単位:ピクセル
-    uint32_t h0 = height/div;                   // 分割した画像の高さ,単位:ピクセル
-    sdReader.SetHeight(bmp, h0);                // 画像の高さ設定,単位:ピクセル
-
-    uint8_t *ptr = (uint8_t *)(bmp+headerSize); // 画像データのポインタ
-    uint32_t size = sdReader.GetSize(bmp)/div;  // 一度で読込む画像データのサイズ計算,単位:バイト
-
-    // 縦方向に分割して読み込みと描画を行う
-    for (int n=0; n<div; n++) 
-    {
-        sdReader.ReadFile(ptr, size);           // 画像データの読み込み
-        GuiBase::GetLcd().DrawBitmap(0, (div-1-n)*h0, bmp);
-    }
-
-    sdReader.Close();                   // ファイルのクローズ
-}
--- a/main.cpp	Sun Oct 21 11:29:47 2018 +0000
+++ b/main.cpp	Tue Oct 23 11:51:47 2018 +0000
@@ -9,7 +9,7 @@
 //          縦: 272 ピクセル,横: 480 ピクセル
 //      縦方向のピクセル数の制約:8 の倍数にすること
 //
-//  2018/10/21, Copyright (c) 2018 MIKAMI, Naoki
+//  2018/10/23, Copyright (c) 2018 MIKAMI, Naoki
 //-----------------------------------------------------------
 
 #include "ReadAndDisplay.hpp"