OSDN Git Service

implement displaying text.
[bbk/bchanf.git] / src / tools / hmi_generator.rb
index 96ca072..ff895a8 100644 (file)
@@ -71,9 +71,24 @@ class HMIParts
   def rect_string()
     "{{" + @yaml["rect"]["left"].to_s + ", " + @yaml["rect"]["top"].to_s + ", " + @yaml["rect"]["right"].to_s + ", " + @yaml["rect"]["bottom"].to_s + "}}";
   end
+  def rect_left()
+    @yaml["rect"]["left"].to_s
+  end
+  def rect_top()
+    @yaml["rect"]["top"].to_s
+  end
+  def rect_right()
+    @yaml["rect"]["right"].to_s
+  end
+  def rect_bottom()
+    @yaml["rect"]["bottom"].to_s
+  end
   def text_array()
     conv_TCArray_to_hex_definition(conv_euc_to_TCArray(@yaml["text"]));
   end
+  def text_array_length()
+    calc_euc_to_TCArray_length(@yaml["text"]);
+  end
   def is_attr_specified()
     @yaml["attr"] != nil
   end
@@ -129,6 +144,9 @@ class HMIParts
   def is_databox_use()
     @yaml["databox"] != nil && (@yaml["databox"]["specify"] != "direct" || @yaml["databox"]["specify"] != "argument")
   end
+  def is_use_rect_in_open()
+    !is_databox_use()
+  end
 
   def generate_header_eventtype_enumulate(main_name, window_name)
     script = <<-EOS
@@ -162,7 +180,7 @@ class HMIParts
     erb.result(binding)
   end
 
-  def generate_source_struct()
+  def generate_source_struct(window_name)
     script = <<-EOS
     EOS
 
@@ -227,6 +245,15 @@ class HMIParts
        if (window-><%= self.name() %>.id < 0) {
                DP_ER("ccre_xxx <%= self.name() %> error:", window-><%= self.name() %>.id);
        }
+       <%- if self.is_databox_use() -%><%= self.generate_loadvalue_in_open() %><%- end -%>
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_loadvalue_in_open()
+    script = <<-EOS
     EOS
 
     erb = ERB.new(script, nil, '-');
@@ -248,6 +275,14 @@ class HMIParts
     erb = ERB.new(script, nil, '-');
     erb.result(binding)
   end
+
+  def generate_draw_in_draw(main_name, window_name)
+    script = <<-EOS
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
 end
 
 class HMITextBoxParts < HMIParts
@@ -321,14 +356,15 @@ typedef struct <%= window_name %>_eventdata_<%= self.name() %>_keymenu_t_ <%= wi
     script = <<-EOS
 IMPORT W <%= window_name %>_set<%= self.name() %>text(<%= window_name %>_t *window, TC *str, W len);
 IMPORT W <%= window_name %>_get<%= self.name() %>text(<%= window_name %>_t *window, TC *str, W len);
-IMPORT W <%= window_name %>_end<%= self.name() %>action(<%= window_name %>_t *window);
+IMPORT W <%= window_name %>_cut<%= self.name() %>text(<%= window_name %>_t *window, TC *str, W len, Bool cut);
+IMPORT W <%= window_name %>_insert<%= self.name() %>text(<%= window_name %>_t *window, TC *str, W len);
     EOS
 
     erb = ERB.new(script, nil, '-');
     erb.result(binding)
   end
 
-  def generate_source_struct()
+  def generate_source_struct(window_name)
     script = <<-EOS
        struct {
                PAID id;
@@ -387,6 +423,45 @@ EXPORT W <%= window_name %>_get<%= self.name() %>text(<%= window_name %>_t *wind
        return cp_len;
 }
 
+EXPORT W <%= window_name %>_cut<%= self.name() %>text(<%= window_name %>_t *window, TC *str, W len, Bool cut)
+{
+       W err, len0;
+
+       len0 = ccut_txt(window-><%= self.name() %>.id, len, str, cut == False ? 0 : 1);
+       if (len0 < 0) {
+               return len0;
+       }
+
+       if (cut != False) {
+               err = cget_val(window-><%= self.name() %>.id, <%= self.text_length() %>, (W*)(window-><%= self.name() %>.buf+<%= self.get_attr_offset() %>));
+               if (err < 0) {
+                       return err;
+               }
+               window-><%= self.name() %>.buf_written = err;
+               return len0;
+       }
+
+       return len0;
+}
+
+EXPORT W <%= window_name %>_insert<%= self.name() %>text(<%= window_name %>_t *window, TC *str, W len)
+{
+       W err;
+
+       err = cins_txt(window-><%= self.name() %>.id, (PNT){0x8000, 0x8000}, str);
+       if (err < 0) {
+               return err;
+       }
+
+       err = cget_val(window-><%= self.name() %>.id, <%= self.text_length() %>, (W*)(window-><%= self.name() %>.buf+<%= self.get_attr_offset() %>));
+       if (err < 0) {
+               return err;
+       }
+       window-><%= self.name() %>.buf_written = err;
+
+       return err;
+}
+
 LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *window, WEVENT *wev, <%= main_name %>event_t *evt)
 {
        W i, len;
@@ -394,8 +469,22 @@ LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *win
        i = cact_par(window-><%= self.name() %>.id, wev);
        if (i & 0x2000) {
                window-><%= self.name() %>.nextaction = True;
-               <%= window_name %>_setflag(window, <%= window_name.upcase %>_FLAG_PARTS_OTHEREVENT);
-               wugt_evt(wev);
+               switch (i) {
+               case    P_MENU:
+                       if ((wev->s.type == EV_KEYDWN)&&(wev->s.stat & ES_CMD)) {
+                               evt->type = <%= main_name.upcase %>EVENT_TYPE_<%= window_name.upcase %>_PARTS_<%= self.name().upcase %>_KEYMENU;
+                               evt->data.<%= window_name %>_<%= self.name() %>_keymenu.keycode = wev->e.data.key.code;
+                       } else {
+                               evt->type = <%= main_name.upcase %>EVENT_TYPE_<%= window_name.upcase %>_PARTS_<%= self.name().upcase %>_MENU;
+                               evt->data.<%= window_name %>_<%= self.name() %>_menu.pos = wev->s.pos;
+                       }
+                       <%= window_name %>_setflag(window, <%= window_name.upcase %>_FLAG_PARTS_NEXTACTION);
+                       break;
+               default:
+                       wugt_evt(wev);
+                       <%= window_name %>_setflag(window, <%= window_name.upcase %>_FLAG_PARTS_OTHEREVENT);
+                       break;
+               }
                return;
        }
        window-><%= self.name() %>.nextaction = False;
@@ -407,6 +496,8 @@ LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *win
        }
        switch (i & 7) {
        case    P_BUT:
+               cchg_par(window-><%= self.name() %>.id, P_INACT);
+               cchg_par(window-><%= self.name() %>.id, P_ACT);
                wugt_evt(wev);
                break;
        case    P_TAB:
@@ -427,18 +518,6 @@ LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *win
                evt->data.<%= window_name %>_<%= self.name() %>_copy.rel_wid = wev->s.wid;
                evt->data.<%= window_name %>_<%= self.name() %>_copy.pos = wev->s.pos;
                break;
-       case    P_MENU:
-               if ((wev->s.type == EV_KEYDWN)&&(wev->s.stat & ES_CMD)) {
-                       evt->type = <%= main_name.upcase %>EVENT_TYPE_<%= window_name.upcase %>_PARTS_<%= self.name().upcase %>_KEYMENU;
-                       evt->data.<%= window_name %>_<%= self.name() %>_keymenu.keycode = wev->e.data.key.code;
-               } else {
-                       evt->type = <%= main_name.upcase %>EVENT_TYPE_<%= window_name.upcase %>_PARTS_<%= self.name().upcase %>_MENU;
-                       evt->data.<%= window_name %>_<%= self.name() %>_menu.pos = wev->s.pos;
-               }
-               window-><%= self.name() %>.nextaction = True;
-               <%= window_name %>_setflag(window, <%= window_name.upcase %>_FLAG_PARTS_NEXTACTION);
-               wugt_evt(wev);
-               break;
        }
 }
 
@@ -481,6 +560,15 @@ LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *win
     erb.result(binding)
   end
 
+  def generate_loadvalue_in_open()
+    script = <<-EOS
+       cset_val(window-><%= self.name() %>.id, <%= self.text_length() %>, (W*)(window-><%= self.name() %>.buf+<%= self.get_attr_offset() %>));
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
   def generate_savevalue_in_close()
     script = <<-EOS
        err = cget_val(window-><%= self.name() %>.id, <%= self.text_length() %>, (W*)(window-><%= self.name() %>.buf+<%= self.get_attr_offset() %>));
@@ -638,7 +726,7 @@ IMPORT W <%= window_name %>_get<%= self.name() %>value(<%= window_name %>_t *win
     erb.result(binding)
   end
 
-  def generate_source_struct()
+  def generate_source_struct(window_name)
     script = <<-EOS
        struct {
                PAID id;
@@ -759,6 +847,15 @@ LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *win
     erb.result(binding)
   end
 
+  def generate_loadvalue_in_open()
+    script = <<-EOS
+       cset_val(window-><%= self.name() %>.id, <% if self.is_double() %>2<% else %>1<% end %>, (W*)(&window-><%= self.name() %>.cv));
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
   def generate_savevalue_in_close()
     script = <<-EOS
        err = cget_val(window-><%= self.name() %>.id, <% if self.is_double() %>2<% else %>1<% end %>, (W*)(&window-><%= self.name() %>.cv));
@@ -791,7 +888,7 @@ class HMITextMomentallySwitchParts < HMIParts
     erb.result(binding)
   end
 
-  def generate_source_struct()
+  def generate_source_struct(window_name)
     script = <<-EOS
        struct {
                PAID id;
@@ -896,7 +993,7 @@ IMPORT W <%= window_name %>_get<%= self.name() %>value(<%= window_name %>_t *win
     erb.result(binding)
   end
 
-  def generate_source_struct()
+  def generate_source_struct(window_name)
     script = <<-EOS
        struct {
                PAID id;
@@ -1044,6 +1141,15 @@ LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *win
     erb.result(binding)
   end
 
+  def generate_loadvalue_in_open()
+    script = <<-EOS
+       cset_val(window-><%= self.name() %>.id, <%= self.calc_serialbox_fieldsnumber() %>, (W*)(window-><%= self.name() %>.cv));
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
   def generate_savevalue_in_close()
     script = <<-EOS
        err = cget_val(window-><%= self.name() %>.id, <%= self.calc_serialbox_fieldsnumber() %>, (W*)(window-><%= self.name() %>.cv));
@@ -1066,6 +1172,216 @@ LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *win
   end
 end
 
+class HMISwitchSelectorParts < HMIParts
+  def calc_formatlength()
+    l = 0;
+    @yaml["fields"].each { |field|
+      l+= 1 + calc_euc_to_TCArray_length(field["text"]);
+    }
+    l += 1; # for last TNULL
+    return l
+  end
+  def is_need_eventbreak()
+    return false
+  end
+
+  def generate_header_eventtype_enumulate(main_name, window_name)
+    script = <<-EOS
+       <%= main_name.upcase %>EVENT_TYPE_<%= window_name.upcase %>_PARTS_<%= self.name().upcase %>_CHANGE,
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_header_eventstruct_definition(main_name, window_name)
+    script = <<-EOS
+struct <%= window_name %>_eventdata_<%= self.name() %>_change_t_ {
+       <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T value;
+};
+typedef struct <%= window_name %>_eventdata_<%= self.name() %>_change_t_ <%= window_name %>_eventdata_<%= self.name() %>_change_t;
+
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_header_eventunion_member(main_name, window_name)
+    script = <<-EOS
+               <%= window_name %>_eventdata_<%= self.name() %>_change_t <%= window_name %>_<%= self.name() %>_change;
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_prototypes(window_name)
+    script = <<-EOS
+enum <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T_ {
+       <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_NOSEL = 0,
+       <%- @yaml["fields"].each do |field| -%>
+       <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_<%= field["name"].upcase %>,
+       <%- end -%>
+};
+typedef enum <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T_ <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T;
+IMPORT W <%= window_name %>_set<%= self.name() %>value(<%= window_name %>_t *window, <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T value);
+IMPORT W <%= window_name %>_get<%= self.name() %>value(<%= window_name %>_t *window, <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T *value);
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_source_struct(window_name)
+    script = <<-EOS
+       struct {
+               PAID id;
+               <%- if self.is_databox_use() -%>
+               W dnum;
+               <%- else -%>
+               TC format[<%= self.calc_formatlength()%>];
+               <%- end -%>
+               <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T value;
+       } <%= self.name() %>;
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_source_functions(main_name, window_name)
+    script = <<-EOS
+EXPORT W <%= window_name %>_set<%= self.name() %>value(<%= window_name %>_t *window, <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T value)
+{
+       W val;
+
+       val = window-><%= self.name() %>.value = value;
+       if (window->wid < 0) {
+               return 0;
+       }
+
+       return cset_val(window-><%= self.name() %>.id, 1, (W*)(&val));
+}
+
+EXPORT W <%= window_name %>_get<%= self.name() %>value(<%= window_name %>_t *window, <%= window_name.upcase %>_<%= self.name().upcase %>VALUE_T *value)
+{
+       W val,err;
+
+       if (window->wid > 0) {
+               err = cget_val(window-><%= self.name() %>.id, 1, (W*)(&val));
+               if (err < 0) {
+                       return err;
+               }
+       }
+       *value = window-><%= self.name() %>.value = val;
+
+       return 0;
+}
+
+LOCAL VOID <%= window_name %>_action<%= self.name() %>(<%= window_name %>_t *window, WEVENT *wev, <%= main_name %>event_t *evt)
+{
+       W i;
+
+       i = cact_par(window-><%= self.name() %>.id, wev);
+       if ((i & 0x5000) != 0x5000) {
+               return;
+       }
+       window-><%= self.name() %>.value = i & 0xfff;
+       evt->type = <%= main_name.upcase %>EVENT_TYPE_<%= window_name.upcase %>_PARTS_<%= self.name().upcase %>_CHANGE;
+       evt->data.<%= window_name %>_<%= self.name() %>_change.value = window-><%= self.name() %>.value;
+}
+
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_initialize_in_new()
+    script = <<-EOS
+       window-><%= self.name() %>.id = -1;
+       <%- if self.is_databox_use() -%>
+       window-><%= self.name() %>.dnum = dnum_<%= self.name() %>;
+       <%- else -%>
+         <%- l = 0 -%>
+         <%- @yaml["fields"].each do |field| -%>
+       window-><%= self.name() %>.format[<%= l %>] = MC_STR;<%- l+=1 %>
+           <%- conv_euc_to_TCArray(field["text"]).each do |ch| -%>
+       window-><%= self.name() %>.format[<%= l %>] = 0x<%= ch.to_s(16) %>;<%- l+=1 %>
+           <%- end -%>
+         <%- end -%>
+       window-><%= self.name() %>.format[<%= l %>] = TNULL;<%- l+=1 %>
+       <%- end -%>
+       window-><%= self.name() %>.value = 0;
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_create_systemcall_direct()
+    script = "ccre_sel(wid, WS_PARTS|P_DISP, &r, window-><%= self.name() %>.value, window-><%= self.name() %>.format, NULL)"
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_loadvalue_in_open()
+    script = <<-EOS
+       cset_val(window-><%= self.name() %>.id, 1, (W*)(&window-><%= self.name() %>.value));
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_savevalue_in_close()
+    script = <<-EOS
+       err = cget_val(window-><%= self.name() %>.id, 1, (W*)(&window-><%= self.name() %>.value));
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+
+  def generate_action_in_butdnwork(main_name, window_name)
+    script = <<-EOS
+       if (id == window-><%= self.name() %>.id) {
+               <%= window_name %>_action<%= self.name() %>(window, wev, evt);
+               return;
+       }
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+end
+
+class HMIFixedTextParts < HMIParts
+  def is_need_eventbreak()
+    return false
+  end
+  def is_use_rect_in_open()
+    return false
+  end
+
+  def generate_initialize_in_new()
+    return ""
+  end
+  def generate_create_in_open()
+    return ""
+  end
+  def generate_draw_in_draw(main_name, window_name)
+    script = <<-EOS
+       gdra_stp(window->gid, <%= self.rect_left() %>, <%= self.rect_bottom() %>, (TC[]){<%= self.text_array() %>}, <%= self.text_array_length() %>, G_STORE);
+    EOS
+
+    erb = ERB.new(script, nil, '-');
+    erb.result(binding)
+  end
+end
+
 def generate_parts(type, a)
   case type
   when "textbox"
@@ -1078,6 +1394,10 @@ def generate_parts(type, a)
     return HMISerialBoxParts.new(a);
   when "numberbox"
     return HMINumberBoxParts.new(a);
+  when "switchselector"
+    return HMISwitchSelectorParts.new(a);
+  when "fixedtext"
+    return HMIFixedTextParts.new(a)
   end
 end
 
@@ -1120,6 +1440,15 @@ class HMIWindow
   def is_attr_resizable()
     self.is_attr_xxx("resizable");
   end
+  def is_attr_opencheckable()
+    self.is_attr_xxx("opencheckable");
+  end
+  def is_attr_subwindow()
+    self.is_attr_xxx("subwindow");
+  end
+  def is_attr_alwaysopen()
+    self.is_attr_xxx("alwaysopen");
+  end
   def is_exportevent_draw()
     self.is_exportevent_xxx("draw");
   end
@@ -1144,6 +1473,11 @@ class HMIWindow
   def is_exist_controllparts()
     @parts.length > 0;
   end
+  def is_exist_use_rect_in_open()
+    @parts.any? { |item|
+      item.is_use_rect_in_open();
+    };
+  end
   def is_need_flag()
     true # tmp
   end
@@ -1161,6 +1495,16 @@ class HMIWindow
         item.is_need_eventbreak();
       };
   end
+  def get_window_parent()
+    @yaml["parent"]
+  end
+  def get_window_title_max_length()
+    len = @yaml["title_max_length"];
+    if len == nil
+      return 128
+    end
+    return len
+  end
 
   def generate_header_eventtype_enumulate(main_name)
     script = <<-EOS
@@ -1227,6 +1571,9 @@ IMPORT W <%= self.struct_name() %>_setworkrect(<%= self.struct_name() %>_t *wind
 IMPORT W <%= self.struct_name() %>_scrollworkarea(<%= self.struct_name() %>_t *window, W dh, W dv);
 IMPORT W <%= self.struct_name() %>_getworkrect(<%= self.struct_name() %>_t *window, RECT *r);
 <%- end -%>
+<%- if self.is_attr_opencheckable() -%>
+IMPORT Bool <%= self.struct_name() %>_isopen(<%= self.struct_name() %>_t *window);
+<%- end -%>
 <%- if self.is_exportevent_paste() -%>
 IMPORT VOID <%= self.struct_name() %>_responsepasterequest(<%= self.struct_name() %>_t *window, W nak, PNT *pos);
 <%- end -%>
@@ -1245,8 +1592,10 @@ IMPORT GID <%= self.struct_name() %>_getGID(<%= self.struct_name() %>_t *window)
 IMPORT WID <%= self.struct_name() %>_getWID(<%= self.struct_name() %>_t *window);
 IMPORT W <%= self.struct_name() %>_settitle(<%= self.struct_name() %>_t *window, TC *title);
 IMPORT Bool <%= self.struct_name() %>_isactive(<%= self.struct_name() %>_t *window);
+<%- if !self.is_attr_alwaysopen() -%>
 IMPORT W <%= self.struct_name() %>_open(<%= self.struct_name() %>_t *window);
 IMPORT VOID <%= self.struct_name() %>_close(<%= self.struct_name() %>_t *window);
+<%- end -%>
 <%- @parts.each do |p| -%><%= p.generate_prototypes(self.struct_name()) %><%- end -%>
     EOS
 
@@ -1256,7 +1605,7 @@ IMPORT VOID <%= self.struct_name() %>_close(<%= self.struct_name() %>_t *window)
 
   def generate_initialize_arguments()
     script = <<-EOS
-<%- if self.is_attr_resizable() -%>RECT *r<% else %>PNT *p<% end %>, WID parent, TC *title, PAT *bgpat<%- @parts.each do |p| -%><% if p.is_databox_specify_argument() %>, W dnum_<%= p.name() %><% end %><%- end -%><%- -%>
+<%- if self.is_attr_resizable() -%>RECT *r<% else %>PNT *p<% end %>, <%- if self.is_attr_subwindow() -%><%= self.get_window_parent() %>_t *parent<%- else -%>WID parent<%- end -%>, TC *title, PAT *bgpat<%- @parts.each do |p| -%><% if p.is_databox_specify_argument() %>, W dnum_<%= p.name() %><% end %><%- end -%><%- -%>
     EOS
 
     erb = ERB.new(script, nil, '-');
@@ -1280,14 +1629,21 @@ struct <%= self.struct_name() %>_t_ {
        <%- end -%>
        WID wid;
        GID gid;
+       <%- if self.is_attr_subwindow() -%>
+       <%= self.get_window_parent() %>_t *parent;
+       <%- else -%>
        WID parent;
+       <%- end -%>
        RECT r;
        PAT bgpat;
        <%- if self.is_attr_scrollable() -%>
        hmi_windowscroll_t wscr;
        <%- end -%>
+       <%- if !self.is_attr_alwaysopen() -%>
+       TC title[<%= self.get_window_title_max_length() %>+1];
+       <%- end -%>
        WEVENT savedwev;
-       <%- @parts.each do |p| -%><%= p.generate_source_struct() %><%- end -%>
+       <%- @parts.each do |p| -%><%= p.generate_source_struct(self.struct_name()) %><%- end -%>
 };
 
     EOS
@@ -1350,6 +1706,16 @@ EXPORT W <%= self.struct_name() %>_getworkrect(<%= self.struct_name() %>_t *wind
 }
 
 <%- end -%>
+<%- if self.is_attr_opencheckable() -%>
+EXPORT Bool <%= self.struct_name() %>_isopen(<%= self.struct_name() %>_t *window)
+{
+       if (window->wid < 0) {
+               return False;
+       }
+       return True;
+}
+
+<%- end -%>
 <%- if self.is_exportevent_paste() -%>
 EXPORT VOID <%= self.struct_name() %>_responsepasterequest(<%= self.struct_name() %>_t *window, W nak, PNT *pos)
 {
@@ -1381,6 +1747,7 @@ EXPORT W <%= self.struct_name() %>_eraseworkarea(<%= self.struct_name() %>_t *wi
 LOCAL VOID <%= self.struct_name() %>_draw(<%= self.struct_name() %>_t *window, RECT *r)
 {
        cdsp_pwd(window->wid, r, P_RDISP);
+       <%- @parts.each do |p| -%><%= p.generate_draw_in_draw(main_name, self.struct_name()) %><%- end -%>
 }
 
 LOCAL VOID <%= self.struct_name() %>_redisp(<%= self.struct_name() %>_t *window)
@@ -1438,7 +1805,13 @@ EXPORT WID <%= self.struct_name() %>_getWID(<%= self.struct_name() %>_t *window)
 
 EXPORT W <%= self.struct_name() %>_settitle(<%= self.struct_name() %>_t *window, TC *title)
 {
+       <%- if !self.is_attr_alwaysopen() -%>
+       tc_strncpy(window->title, title, <%= self.get_window_title_max_length() %>);
+       window->title[<%= self.get_window_title_max_length() %>] = TNULL;
+       return wset_tit(window->wid, -1, window->title, 0);
+       <%- else -%>
        return wset_tit(window->wid, -1, title, 0);
+       <%- end -%>
 }
 
 EXPORT Bool <%= self.struct_name() %>_isactive(<%= self.struct_name() %>_t *window)
@@ -1499,13 +1872,10 @@ LOCAL VOID <%= self.struct_name() %>_resize(<%= self.struct_name() %>_t *window,
 }
 
 <%- end -%>
-EXPORT W <%= self.struct_name() %>_open(<%= self.struct_name() %>_t *window)
+<% if self.is_attr_alwaysopen() %>LOCAL<% else %>EXPORT<% end %> W <%= self.struct_name() %>_open(<%= self.struct_name() %>_t *window<% if self.is_attr_alwaysopen() %>, TC *title<% end %>)
 {
        WID wid;
-       <%- if self.get_window_title() != nil -%>
-       TC title[] = {<%= conv_TCArray_to_hex_definition(conv_euc_to_TCArray(self.get_window_title())) %>};
-       <%- end -%>
-       <%- if self.is_exist_controllparts() -%>
+       <%- if self.is_exist_use_rect_in_open() -%>
        RECT r;
        <%- end -%>
 
@@ -1513,7 +1883,7 @@ EXPORT W <%= self.struct_name() %>_open(<%= self.struct_name() %>_t *window)
                return 0;
        }
 
-       wid = wopn_wnd(WA_STD<% if self.is_attr_resizable() %>|WA_SIZE|WA_HHDL|WA_VHDL<% end %><% if self.is_attr_scrollable() %>|WA_BBAR|WA_RBAR<% end %>, window->parent, &(window->r), NULL, 2, <%- if self.get_window_title() != nil -%>title<%- else -%>NULL<%- end -%>, &window->bgpat, NULL);
+       wid = wopn_wnd(WA_STD<% if self.is_attr_subwindow() %>|WA_SUBW<% end %><% if self.is_attr_resizable() %>|WA_SIZE|WA_HHDL|WA_VHDL<% end %><% if self.is_attr_scrollable() %>|WA_BBAR|WA_RBAR<% end %>, <% if self.is_attr_subwindow() %>window->parent->wid<% else %>window->parent<% end %>, &(window->r), NULL, 2, <% if !self.is_attr_alwaysopen() %>window->title<%- else -%>title<%- end -%>, &window->bgpat, NULL);
        if (wid < 0) {
                DP_ER("wopn_wnd: subjectoption error", wid);
                return wid;
@@ -1531,6 +1901,7 @@ EXPORT W <%= self.struct_name() %>_open(<%= self.struct_name() %>_t *window)
        return 0;
 }
 
+<%- if !self.is_attr_alwaysopen() -%>
 EXPORT VOID <%= self.struct_name() %>_close(<%= self.struct_name() %>_t *window)
 {
        WDSTAT stat;
@@ -1554,6 +1925,7 @@ EXPORT VOID <%= self.struct_name() %>_close(<%= self.struct_name() %>_t *window)
        window->gid = -1;
 }
 
+<%- end -%>
     EOS
 
     erb = ERB.new(script, nil, '-');
@@ -1620,8 +1992,30 @@ EXPORT <%= self.struct_name() %>_t* <%= self.struct_name() %>_new(<%= self.gener
                return NULL;
        }
        <%- end -%>
+       <%- if !self.is_attr_alwaysopen() -%>
+       tc_strset(window->title, TNULL, <%= self.get_window_title_max_length() %>+1);
+       if (title != 0) {
+               tc_strncpy(window->title, title, <%= self.get_window_title_max_length() %>);
+       } else {
+               <%- l = 0 -%>
+               <%- conv_euc_to_TCArray(self.get_window_title()).each do |ch| -%>
+               window->title[<%= l %>] = 0x<%= ch.to_s(16) %>;<%- l+=1 %>
+               <%- end -%>
+       }
+       <%- end -%>
        <%- @parts.each do |p| -%><%= p.generate_initialize_in_new() %><%- end -%>
 
+       <%- if self.is_attr_alwaysopen() -%>
+       err = <%= self.struct_name() %>_open(window, title);
+       if (err < 0) {
+               <%- if self.is_attr_scrollable() -%>
+               hmi_windowscroll_finalize(&window->wscr);
+               <%- end -%>
+               free(window);
+               return NULL;
+       }
+       <%- end -%>
+
        return window;
 }
 
@@ -2344,6 +2738,11 @@ struct <%= self.main_name() %>_t_ {
 <%- @win.each do |w| -%>
 EXPORT <%= w.struct_name() %>_t* <%= self.main_name() %>_new<%= w.struct_name() %>(<%= self.main_name() %>_t *hmi, <%= w.generate_initialize_arguments() %>)
 {
+       <%- if w.is_attr_subwindow -%>
+       if (parent == NULL) {
+               return NULL;
+       }
+       <%- end -%>
        if (hmi-><%= w.struct_name() %> != NULL) {
                return NULL;
        }