samedi 2 mai 2020

CreateWindowW() fails a first time and then works afterwards [C++]

So I'm trying to program an application that will help me log something and facilitate my actions in the future.

I wanted to make it as simple as possible, so I decided to use Win32API.

So I've made the necessary and created the windows/styles I needed, etcetera.

But there is something that triggers me a lot:

When I click on a button called "Add attendee," a window shall popup and asks me an attendee's name.

But when I click it a first time, nothing happens. But when I click it a second time, aforementioned window appears naturally.

So as to discover which problem it is, I decided to put the GetLastError() function, but it unfortunately returned 0 whenever I click on the "Add attendee" button a first time(when the window doesn't popup).

To know whether CreateWindowW() is the problem or not, I put std::clog << "Test" << std::endl; at the beginning of the WM_CREATE event. And as expected, the text doesn't show up a first time of clicking but it does a second time.

To know further, I decided to do the following:

  • Put std::clog << "Test1" << std::endl; before CreateWindowW();
  • Put std::clog << "Test2" << std::endl; after CreateWindowW();
  • Put std::clog << "Test3" << std::endl; at the beginning of the WM_CREATE event;
  • Put std::clog << GetLastError() << std::endl; after std::clog << "Test2" << std::endl;.

Gotten results:

A first time:

  • "Test1" is successfully written;

  • "Test2" is successfully written;

  • "Test3" fails and doesn't show up;

  • GetLastError() returns 0.

A second time:

  • "Test1" is successfully written;

  • "Test2" is successfully written;

  • "Test3" is successfully written;

  • GetLastError() returns 0.

After this, I then tried the following:

  • Put std::clog << "Terminate" << std::endl; at the beginning of the WM_DESTROY and WM_CLOSE events.

And as expected, "Terminate" is not written when I click on the "Add attendee" button a first time, and it does show up a second time when I close the window.

So according to the obtained results, I then deduced that the problem comes from CreateWindowW(). But the real question is why? GetLastError() returns 0, so normally everything shall be fine.

Here are the parts of my code that imply aforesaid results, have fun:

                case AddAttendee:{
                    if(!LogExisting){
                        MessageBoxW(hwnd, L"No existing log  currently.", L"Error 404 - No log found", MB_OK | MB_ICONERROR);
                        break;
                    }
                    if(IsWindowOpen){
                        MessageBoxW(hwnd, L"Cannot perform such an action; another window is already open.", L"", MB_ICONERROR | MB_OK);
                        break;
                    }
                    memset(&wc, 0, sizeof(wc));
                    HINSTANCE hin;
                    wc.hbrBackground = CreateSolidBrush(RGB(255, 255,255));
                    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
                    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
                    wc.hInstance = hin;
                    wc.lpszClassName = L"HAddAttendee";
                    wc.lpfnWndProc = [](HWND hwnd3, UINT msg3, WPARAM wp3, LPARAM lp3)->LRESULT CALLBACK{
                          switch(msg3){
                              case WM_CTLCOLORSTATIC:{
                                  HDC dc = GetDC(reinterpret_cast<HWND>(wp3));
                                  SetBkColor(dc, RGB(255, 255, 255));
                                  return reinterpret_cast<UINT_PTR>(CreateSolidBrush(RGB(255, 255, 255)));
                              }
                              case WM_COMMAND:{
                                  switch(wp3){
                                      case AttendeeButton:{
                                          std::allocator<char> Alloc;
                                          char name[512], Rank[256];
                                          GetWindowText(hAddEdit, name, sizeof(name));
                                          GetWindowText(hRank, Rank, sizeof(Rank));
                                          if(strcmp(name, "") == 0 || strcmp(Rank, "") == 0){
                                              MessageBoxW(hwnd3, L"One of the fields is empty, please fill it.", L"", MB_OK | MB_ICONERROR);
                                              break;
                                          }
                                          if(GeneralDatabase.find(name) != GeneralDatabase.end()){
                                              DestroyWindow(hwnd3);
                                              MessageBoxW(GeneralWindowHandler, L"Name is already existing.", L"", MB_OK | MB_ICONERROR);
                                              memset(&hwnd3, 0, sizeof(hwnd3));
                                              break;
                                          }
                                          GeneralDatabase[std::string(name)] = std::vector<std::string>{std::string(Rank), "0"};
                                          IsWindowOpen = false;
                                          std::string Name;
                                          Name.append(std::string(name));
                                          TemporaryName = Name;
                                          Name.append(std::string("("));
                                          Name.append(std::string(Rank));
                                          Name.append(std::string(")"));
                                          std::wstring NameW(Name.begin(), Name.end());
                                          SendMessageW(hListAtt, LB_ADDSTRING, (WPARAM)0, (LPARAM)NameW.c_str());
                                          char* score = Alloc.allocate(2);
                                          itoa(MaxScoreVal, score, 10);
                                          std::string Sentence = "0/" + std::string(score);
                                          std::wstring SentenceW(Sentence.begin(), Sentence.end());
                                          SendMessageW(hListScore, LB_ADDSTRING, (WPARAM)0, (LPARAM)SentenceW.c_str());
                                          DestroyWindow(hwnd3);
                                          memset(&hwnd3, 0, sizeof(hwnd3));

                                          Alloc.deallocate(score, 2);
                                          break;
                                      }
                                  }
                                  break;
                              }
                              case WM_CLOSE:{
                                          char name[512], Rank[256];
                                          GetWindowText(hAddEdit, name, sizeof(name));
                                          GetWindowText(hRank, Rank, sizeof(Rank));
                                          if(strcmp(name, "") == 0 || strcmp(Rank, "") == 0){
                                              MessageBoxW(hwnd3, L"One of the fields is empty, please fill it.", L"", MB_OK | MB_ICONERROR);
                                              break;
                                          }
                                          if(GeneralDatabase.find(name) != GeneralDatabase.end()){
                                              DestroyWindow(hwnd3);
                                              MessageBoxW(GeneralWindowHandler, L"Name is already existing.", L"", MB_OK | MB_ICONERROR);
                                              memset(&hwnd3, 0, sizeof(hwnd3));
                                              break;
                                          }

                                          GeneralDatabase[std::string(name)] = std::vector<std::string>{std::string(Rank), "0"};
                                          IsWindowOpen = false;
                                          std::string Name;
                                          Name.append(std::string(name));
                                          TemporaryName = Name;
                                          Name.append(std::string("("));
                                          Name.append(std::string(Rank));
                                          Name.append(std::string(")"));
                                          std::wstring NameW(Name.begin(), Name.end());
                                          SendMessageW(hListAtt, LB_ADDSTRING, (WPARAM)0, (LPARAM)NameW.c_str());
                                          std::allocator<char> Alloc;
                                          char* score = Alloc.allocate(2);
                                          itoa(MaxScoreVal, score, 10);
                                          std::string Sentence = "0/" + std::string(score);
                                          std::wstring SentenceW(Sentence.begin(), Sentence.end());
                                          SendMessageW(hListScore, LB_ADDSTRING, (WPARAM)0, (LPARAM)SentenceW.c_str());
                                          DestroyWindow(hwnd3);
                                          memset(&hwnd3, 0, sizeof(hwnd3));

                                          Alloc.deallocate(score, 2);
                                          break;
                              }
                              case WM_CREATE:{
                                  IsWindowOpen = true;

                                  SendMessageW(CreateWindowW(L"Static", L"Name : ", WS_VISIBLE | WS_CHILD, 5, 25, 55, 20, hwnd3, 0, 0, 0), WM_SETFONT, (WPARAM)CreateFontW(20, 0, 0, 0, FF_DONTCARE, 0, 0, 0, 0,0,0,0,0, L"Georgia"), (LPARAM)TRUE);

                                  hAddEdit = CreateWindowW(L"Edit", L"", WS_VISIBLE | WS_CHILD | ES_AUTOHSCROLL | WS_BORDER, 75, 27, 215, 20, hwnd3, 0, 0, 0);

                                  hAddAttBut = CreateWindowW(L"Button", L"Insert", WS_VISIBLE | WS_CHILD | WS_BORDER, 110, 170, 80, 40,  hwnd3, (HMENU)AttendeeButton, 0, 0);

                                  SendMessageW(CreateWindowW(L"Static", L"Rank : ", WS_VISIBLE | WS_CHILD, 5, 75, 55, 20, hwnd3, 0 ,0 ,0), WM_SETFONT, (WPARAM)CreateFontW(20, 0, 0, 0, FF_DONTCARE, 0, 0, 0, 0,0,0,0,0, L"Georgia"), (LPARAM)TRUE);
                                  hRank = CreateWindowW(L"ComboBox", L"", WS_VISIBLE | WS_CHILD | CBS_DROPDOWN | CBS_DROPDOWNLIST, 75, 77, 215, 120, hwnd3, 0, 0, 0);
                                  if(strcmp(TypeVal.c_str(), "Joint departmental training") == 0){
                                      SendMessageW(hRank, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"SD");
                                      SendMessageW(hRank, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"MTF");
                                  }
                                  else if(strcmp(TypeVal.c_str(), "Cadet test") == 0){
                                      SendMessageW(hRank, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"Cadet");
                                      SendMessageW(hRank, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
                                      EnableWindow(hRank, false);
                                  }
                                  else{
                                      SendMessageW(hRank, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"Cadet");
                                      SendMessageW(hRank, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"Junior");
                                      SendMessageW(hRank, CB_ADDSTRING, (WPARAM)0, (LPARAM)L"Sentinel");
                                  }
                                  break;
                              }
                              case WM_DESTROY:{
                                  std::clog << GetLastError() << std::endl;
                                  if(!TemporaryName.empty()){

                                      AddListString(TemporaryName);
                                      TemporaryName = "";
                                  }
                                  DestroyWindow(hwnd3);
                                  memset(&hwnd3, 0, sizeof(hwnd3));
                                  IsWindowOpen = false;

                                  break;
                              }
                              default:{
                                  DefWindowProcW(hwnd3, msg3, wp3, lp3);

                              }
                          }
                      };
                    if(IsAttendeeRegistered == false){
                       IsAttendeeRegistered = true;
                       if(!RegisterClassW(&wc)){
                          MessageBoxW(hwnd, L"Failed to register.", L"", MB_OK | MB_ICONERROR);
                          break;
                       }
                    }
                    CreateWindowW(L"HAddAttendee", L"Insert attendee to the list", WS_VISIBLE | WS_SYSMENU | WS_MINIMIZEBOX, ((xScreen/2)-150), ((yScreen/2)-125), 300, 250, 0, 0, 0, 0);
                    break;

Aucun commentaire:

Enregistrer un commentaire