void InteractiveOutputTestCase::TestDllListLoaded() { #ifdef TEST_DYNLIB wxPuts(wxT("*** testing wxDynamicLibrary::ListLoaded() ***\n")); wxPuts("Loaded modules:"); wxDynamicLibraryDetailsArray dlls = wxDynamicLibrary::ListLoaded(); const size_t count = dlls.GetCount(); for ( size_t n = 0; n < count; ++n ) { const wxDynamicLibraryDetails& details = dlls[n]; printf("%-45s", (const char *)details.GetPath().mb_str()); void *addr wxDUMMY_INITIALIZE(NULL); size_t len wxDUMMY_INITIALIZE(0); if ( details.GetAddress(&addr, &len) ) { printf(" %08lx:%08lx", (unsigned long)addr, (unsigned long)((char *)addr + len)); } printf(" %s\n", (const char *)details.GetVersion().mb_str()); } wxPuts(wxEmptyString); #endif // TEST_DYNLIB }
bool wxTabCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) { wxTabEvent event(wxEVT_NULL, m_windowId); wxEventType eventType wxDUMMY_INITIALIZE(wxEVT_NULL); NMHDR* hdr1 = (NMHDR*) lParam; switch ( hdr1->code ) { case TCN_SELCHANGE: eventType = wxEVT_COMMAND_TAB_SEL_CHANGED; break; case TCN_SELCHANGING: eventType = wxEVT_COMMAND_TAB_SEL_CHANGING; break; #ifndef __WXWINCE__ case TTN_NEEDTEXT: { // TODO // if (!tool->m_shortHelpString.empty()) // ttText->lpszText = (char *) (const char *)tool->m_shortHelpString; } #endif default : return wxControl::MSWOnNotify(idCtrl, lParam, result); } event.SetEventObject( this ); event.SetEventType(eventType); event.SetInt(idCtrl) ; event.SetSelection(idCtrl); return ProcessEvent(event); }
// Create a drag image from a bitmap and optional cursor bool wxDragImage::Create(const wxBitmap& image, const wxCursor& cursor) { if ( m_hImageList ) ImageList_Destroy(GetHimageList()); m_hImageList = 0; #ifdef __WXWINCE__ UINT flags = ILC_COLOR; #else UINT flags wxDUMMY_INITIALIZE(0) ; if (image.GetDepth() <= 4) flags = ILC_COLOR4; else if (image.GetDepth() <= 8) flags = ILC_COLOR8; else if (image.GetDepth() <= 16) flags = ILC_COLOR16; else if (image.GetDepth() <= 24) flags = ILC_COLOR24; else flags = ILC_COLOR32; #endif bool mask = (image.GetMask() != 0); // Curiously, even if the image doesn't have a mask, // we still have to use ILC_MASK or the image won't show // up when dragged. // if ( mask ) flags |= ILC_MASK; m_hImageList = (WXHIMAGELIST) ImageList_Create(image.GetWidth(), image.GetHeight(), flags, 1, 1); int index; if (!mask) { HBITMAP hBitmap1 = (HBITMAP) image.GetHBITMAP(); index = ImageList_Add(GetHimageList(), hBitmap1, 0); } else { HBITMAP hBitmap1 = (HBITMAP) image.GetHBITMAP(); HBITMAP hBitmap2 = (HBITMAP) image.GetMask()->GetMaskBitmap(); HBITMAP hbmpMask = wxInvertMask(hBitmap2); index = ImageList_Add(GetHimageList(), hBitmap1, hbmpMask); ::DeleteObject(hbmpMask); } if ( index == -1 ) { wxLogError(_("Couldn't add an image to the image list.")); } m_cursor = cursor; // Can only combine with drag image after calling BeginDrag. return (index != -1) ; }
bool wxControl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM* result) { wxEventType eventType wxDUMMY_INITIALIZE(wxEVT_NULL); NMHDR *hdr = (NMHDR*) lParam; switch ( hdr->code ) { case NM_CLICK: eventType = wxEVT_COMMAND_LEFT_CLICK; break; case NM_DBLCLK: eventType = wxEVT_COMMAND_LEFT_DCLICK; break; case NM_RCLICK: eventType = wxEVT_COMMAND_RIGHT_CLICK; break; case NM_RDBLCLK: eventType = wxEVT_COMMAND_RIGHT_DCLICK; break; case NM_SETFOCUS: eventType = wxEVT_COMMAND_SET_FOCUS; break; case NM_KILLFOCUS: eventType = wxEVT_COMMAND_KILL_FOCUS; break; case NM_RETURN: eventType = wxEVT_COMMAND_ENTER; break; default: return wxWindow::MSWOnNotify(idCtrl, lParam, result); } wxCommandEvent event(wxEVT_NULL, m_windowId); event.SetEventType(eventType); event.SetEventObject(this); return GetEventHandler()->ProcessEvent(event); }
void wxEmulatorContainer::OnEraseBackground(wxEraseEvent& event) { wxDC* dc wxDUMMY_INITIALIZE(NULL); if (event.GetDC()) { dc = event.GetDC(); } else { dc = new wxClientDC(this); } dc->SetBackground(wxBrush(wxGetApp().m_emulatorInfo.m_emulatorBackgroundColour, wxSOLID)); dc->Clear(); if (!event.GetDC()) delete dc; }
wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id, const wxString& name) { wxStatusBar *statusBar wxDUMMY_INITIALIZE(NULL); #if wxUSE_NATIVE_STATUSBAR if ( !UsesNativeStatusBar() ) { statusBar = (wxStatusBar *)new wxStatusBarGeneric(this, id, style); } else #endif { statusBar = new wxStatusBar(this, id, style, name); } statusBar->SetFieldsCount(number); return statusBar; }
// Create a drag image from an icon and optional cursor bool wxDragImage::Create(const wxIcon& image, const wxCursor& cursor) { if ( m_hImageList ) ImageList_Destroy(GetHimageList()); m_hImageList = 0; #ifdef __WXWINCE__ UINT flags = ILC_COLOR; #else UINT flags wxDUMMY_INITIALIZE(0) ; if (image.GetDepth() <= 4) flags = ILC_COLOR4; else if (image.GetDepth() <= 8) flags = ILC_COLOR8; else if (image.GetDepth() <= 16) flags = ILC_COLOR16; else if (image.GetDepth() <= 24) flags = ILC_COLOR24; else flags = ILC_COLOR32; #endif flags |= ILC_MASK; m_hImageList = (WXHIMAGELIST) ImageList_Create(image.GetWidth(), image.GetHeight(), flags, 1, 1); HICON hIcon = (HICON) image.GetHICON(); int index = ImageList_AddIcon(GetHimageList(), hIcon); if ( index == -1 ) { wxLogError(_("Couldn't add an image to the image list.")); } m_cursor = cursor; // Can only combine with drag image after calling BeginDrag. return (index != -1) ; }
bool wxFSWatcherImplMSW::DoSetUpWatch(wxFSWatchEntryMSW& watch) { BOOL bWatchSubtree wxDUMMY_INITIALIZE(FALSE); switch ( watch.GetType() ) { case wxFSWPath_File: wxLogError(_("Monitoring individual files for changes is not " "supported currently.")); return false; case wxFSWPath_Dir: bWatchSubtree = FALSE; break; case wxFSWPath_Tree: bWatchSubtree = TRUE; break; case wxFSWPath_None: wxFAIL_MSG( "Invalid watch type." ); return false; } int flags = Watcher2NativeFlags(watch.GetFlags()); int ret = ReadDirectoryChangesW(watch.GetHandle(), watch.GetBuffer(), wxFSWatchEntryMSW::BUFFER_SIZE, bWatchSubtree, flags, NULL, watch.GetOverlapped(), NULL); if (!ret) { wxLogSysError(_("Unable to set up watch for '%s'"), watch.GetPath()); } return ret != 0; }
bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt) { sm_abortIt = false; sm_abortWindow = NULL; if (!printout) { sm_lastError = wxPRINTER_ERROR; return false; } if (m_printDialogData.GetMinPage() < 1) m_printDialogData.SetMinPage(1); if (m_printDialogData.GetMaxPage() < 1) m_printDialogData.SetMaxPage(9999); // Create a suitable device context wxPrinterDC *dc wxDUMMY_INITIALIZE(NULL); if (prompt) { dc = wxDynamicCast(PrintDialog(parent), wxPrinterDC); if (!dc) return false; } else { dc = new wxPrinterDC(m_printDialogData.GetPrintData()); } // May have pressed cancel. if (!dc || !dc->IsOk()) { if (dc) delete dc; return false; } // Set printout parameters if (!printout->SetUp(*dc)) { delete dc; sm_lastError = wxPRINTER_ERROR; return false; } // Create an abort window wxBusyCursor busyCursor; printout->OnPreparePrinting(); // Get some parameters from the printout, if defined int fromPage, toPage; int minPage, maxPage; printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage); if (maxPage == 0) { sm_lastError = wxPRINTER_ERROR; return false; } // Only set min and max, because from and to have been // set by the user m_printDialogData.SetMinPage(minPage); m_printDialogData.SetMaxPage(maxPage); wxPrintAbortDialog *win = CreateAbortWindow(parent, printout); wxYield(); ::SetAbortProc(GetHdcOf(*dc), wxAbortProc); if (!win) { wxLogDebug(wxT("Could not create an abort dialog.")); sm_lastError = wxPRINTER_ERROR; delete dc; return false; } sm_abortWindow = win; sm_abortWindow->Show(); wxSafeYield(); printout->OnBeginPrinting(); sm_lastError = wxPRINTER_NO_ERROR; int minPageNum = minPage, maxPageNum = maxPage; if ( !(m_printDialogData.GetAllPages() || m_printDialogData.GetSelection()) ) { minPageNum = m_printDialogData.GetFromPage(); maxPageNum = m_printDialogData.GetToPage(); } // The dc we get from the PrintDialog will do multiple copies without help // if the device supports it. Loop only if we have created a dc from our // own m_printDialogData or the device does not support multiple copies. // m_printDialogData.GetPrintData().GetNoCopies() is set from device // devMode in printdlg.cpp/wxWindowsPrintDialog::ConvertFromNative() const int maxCopyCount = !prompt || !m_printDialogData.GetPrintData().GetNoCopies() ? m_printDialogData.GetNoCopies() : 1; for ( int copyCount = 1; copyCount <= maxCopyCount; copyCount++ ) { if ( !printout->OnBeginDocument(minPageNum, maxPageNum) ) { wxLogError(_("Could not start printing.")); sm_lastError = wxPRINTER_ERROR; break; } if (sm_abortIt) { sm_lastError = wxPRINTER_CANCELLED; break; } int pn; for ( pn = minPageNum; pn <= maxPageNum && printout->HasPage(pn); pn++ ) { win->SetProgress(pn - minPageNum + 1, maxPageNum - minPageNum + 1, copyCount, maxCopyCount); if ( sm_abortIt ) { sm_lastError = wxPRINTER_CANCELLED; break; } dc->StartPage(); bool cont = printout->OnPrintPage(pn); dc->EndPage(); if ( !cont ) { sm_lastError = wxPRINTER_CANCELLED; break; } } printout->OnEndDocument(); } printout->OnEndPrinting(); if (sm_abortWindow) { sm_abortWindow->Show(false); wxDELETE(sm_abortWindow); } delete dc; return sm_lastError == wxPRINTER_NO_ERROR; }
wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, const wxString *source, const wxString::const_iterator& pos, const wxString::const_iterator& end_pos, wxHtmlTagsCache *cache, wxHtmlEntitiesParser *entParser) { /* Setup DOM relations */ m_Next = NULL; m_FirstChild = m_LastChild = NULL; m_Parent = parent; if (parent) { m_Prev = m_Parent->m_LastChild; if (m_Prev == NULL) m_Parent->m_FirstChild = this; else m_Prev->m_Next = this; m_Parent->m_LastChild = this; } else m_Prev = NULL; /* Find parameters and their values: */ wxChar c wxDUMMY_INITIALIZE(0); // fill-in name, params and begin pos: wxString::const_iterator i(pos+1); // find tag's name and convert it to uppercase: while ((i < end_pos) && ((c = *(i++)) != wxT(' ') && c != wxT('\r') && c != wxT('\n') && c != wxT('\t') && c != wxT('>') && c != wxT('/'))) { if ((c >= wxT('a')) && (c <= wxT('z'))) c -= (wxT('a') - wxT('A')); m_Name << c; } // if the tag has parameters, read them and "normalize" them, // i.e. convert to uppercase, replace whitespaces by spaces and // remove whitespaces around '=': if (*(i-1) != wxT('>')) { #define IS_WHITE(c) (c == wxT(' ') || c == wxT('\r') || \ c == wxT('\n') || c == wxT('\t')) wxString pname, pvalue; wxChar quote; enum { ST_BEFORE_NAME = 1, ST_NAME, ST_BEFORE_EQ, ST_BEFORE_VALUE, ST_VALUE } state; quote = 0; state = ST_BEFORE_NAME; while (i < end_pos) { c = *(i++); if (c == wxT('>') && !(state == ST_VALUE && quote != 0)) { if (state == ST_BEFORE_EQ || state == ST_NAME) { m_ParamNames.Add(pname); m_ParamValues.Add(wxGetEmptyString()); } else if (state == ST_VALUE && quote == 0) { m_ParamNames.Add(pname); if (entParser) m_ParamValues.Add(entParser->Parse(pvalue)); else m_ParamValues.Add(pvalue); } break; } switch (state) { case ST_BEFORE_NAME: if (!IS_WHITE(c)) { pname = c; state = ST_NAME; } break; case ST_NAME: if (IS_WHITE(c)) state = ST_BEFORE_EQ; else if (c == wxT('=')) state = ST_BEFORE_VALUE; else pname << c; break; case ST_BEFORE_EQ: if (c == wxT('=')) state = ST_BEFORE_VALUE; else if (!IS_WHITE(c)) { m_ParamNames.Add(pname); m_ParamValues.Add(wxGetEmptyString()); pname = c; state = ST_NAME; } break; case ST_BEFORE_VALUE: if (!IS_WHITE(c)) { if (c == wxT('"') || c == wxT('\'')) quote = c, pvalue = wxGetEmptyString(); else quote = 0, pvalue = c; state = ST_VALUE; } break; case ST_VALUE: if ((quote != 0 && c == quote) || (quote == 0 && IS_WHITE(c))) { m_ParamNames.Add(pname); if (quote == 0) { // VS: backward compatibility, no real reason, // but wxHTML code relies on this... :( pvalue.MakeUpper(); } if (entParser) m_ParamValues.Add(entParser->Parse(pvalue)); else m_ParamValues.Add(pvalue); state = ST_BEFORE_NAME; } else pvalue << c; break; } } #undef IS_WHITE } m_Begin = i; cache->QueryTag(pos, source->end(), &m_End1, &m_End2, &m_hasEnding); if (m_End1 > end_pos) m_End1 = end_pos; if (m_End2 > end_pos) m_End2 = end_pos; #if WXWIN_COMPATIBILITY_2_8 m_sourceStart = source->begin(); #endif // Try to parse any style parameters that can be handled simply by // converting them to the equivalent HTML 3 attributes: this is a far cry // from perfect but better than nothing. static const struct EquivAttr { const char *style; const char *attr; } equivAttrs[] = { { "text-align", "ALIGN" }, { "width", "WIDTH" }, { "vertical-align", "VALIGN" }, { "background", "BGCOLOR" }, }; wxHtmlStyleParams styleParams(*this); for ( unsigned n = 0; n < WXSIZEOF(equivAttrs); n++ ) { const EquivAttr& ea = equivAttrs[n]; if ( styleParams.HasParam(ea.style) && !HasParam(ea.attr) ) { m_ParamNames.Add(ea.attr); m_ParamValues.Add(styleParams.GetParam(ea.style)); } } }
int wxKill(long pid, wxSignal sig, wxKillError *krc, int flags) { if (flags & wxKILL_CHILDREN) wxKillAllChildren(pid, sig, krc); // get the process handle to operate on HANDLE hProcess = ::OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, FALSE, // not inheritable (DWORD)pid); if ( hProcess == NULL ) { if ( krc ) { // recognize wxKILL_ACCESS_DENIED as special because this doesn't // mean that the process doesn't exist and this is important for // wxProcess::Exists() *krc = ::GetLastError() == ERROR_ACCESS_DENIED ? wxKILL_ACCESS_DENIED : wxKILL_NO_PROCESS; } return -1; } wxON_BLOCK_EXIT1(::CloseHandle, hProcess); bool ok = true; switch ( sig ) { case wxSIGKILL: // kill the process forcefully returning -1 as error code if ( !::TerminateProcess(hProcess, (UINT)-1) ) { wxLogSysError(_("Failed to kill process %d"), pid); if ( krc ) { // this is not supposed to happen if we could open the // process *krc = wxKILL_ERROR; } ok = false; } break; case wxSIGNONE: // do nothing, we just want to test for process existence if ( krc ) *krc = wxKILL_OK; return 0; default: // any other signal means "terminate" { wxFindByPidParams params; params.pid = (DWORD)pid; // EnumWindows() has nice semantics: it returns 0 if it found // something or if an error occurred and non zero if it // enumerated all the window if ( !::EnumWindows(wxEnumFindByPidProc, (LPARAM)¶ms) ) { // did we find any window? if ( params.hwnd ) { // tell the app to close // // NB: this is the harshest way, the app won't have an // opportunity to save any files, for example, but // this is probably what we want here. If not we // can also use SendMesageTimeout(WM_CLOSE) if ( !::PostMessage(params.hwnd, WM_QUIT, 0, 0) ) { wxLogLastError(_T("PostMessage(WM_QUIT)")); } } else // it was an error then { wxLogLastError(_T("EnumWindows")); ok = false; } } else // no windows for this PID { if ( krc ) *krc = wxKILL_ERROR; ok = false; } } } // the return code DWORD rc wxDUMMY_INITIALIZE(0); if ( ok ) { // as we wait for a short time, we can use just WaitForSingleObject() // and not MsgWaitForMultipleObjects() switch ( ::WaitForSingleObject(hProcess, 500 /* msec */) ) { case WAIT_OBJECT_0: // process terminated if ( !::GetExitCodeProcess(hProcess, &rc) ) { wxLogLastError(_T("GetExitCodeProcess")); } break; default: wxFAIL_MSG( _T("unexpected WaitForSingleObject() return") ); // fall through case WAIT_FAILED: wxLogLastError(_T("WaitForSingleObject")); // fall through case WAIT_TIMEOUT: if ( krc ) *krc = wxKILL_ERROR; rc = STILL_ACTIVE; break; } } // the return code is the same as from Unix kill(): 0 if killed // successfully or -1 on error if ( !ok || rc == STILL_ACTIVE ) return -1; if ( krc ) *krc = wxKILL_OK; return 0; }
bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt) { sm_abortIt = false; sm_abortWindow = NULL; if (!printout) { sm_lastError = wxPRINTER_ERROR; return false; } printout->SetIsPreview(false); if (m_printDialogData.GetMinPage() < 1) m_printDialogData.SetMinPage(1); if (m_printDialogData.GetMaxPage() < 1) m_printDialogData.SetMaxPage(9999); // Create a suitable device context wxPrinterDC *dc wxDUMMY_INITIALIZE(NULL); if (prompt) { dc = wxDynamicCast(PrintDialog(parent), wxPrinterDC); if (!dc) return false; } else { dc = new wxPrinterDC(m_printDialogData.GetPrintData()); } // May have pressed cancel. if (!dc || !dc->Ok()) { if (dc) delete dc; return false; } HDC hdc = ::GetDC(NULL); int logPPIScreenX = ::GetDeviceCaps(hdc, LOGPIXELSX); int logPPIScreenY = ::GetDeviceCaps(hdc, LOGPIXELSY); ::ReleaseDC(NULL, hdc); int logPPIPrinterX = ::GetDeviceCaps((HDC) dc->GetHDC(), LOGPIXELSX); int logPPIPrinterY = ::GetDeviceCaps((HDC) dc->GetHDC(), LOGPIXELSY); if (logPPIPrinterX == 0 || logPPIPrinterY == 0) { delete dc; sm_lastError = wxPRINTER_ERROR; return false; } printout->SetPPIScreen(logPPIScreenX, logPPIScreenY); printout->SetPPIPrinter(logPPIPrinterX, logPPIPrinterY); // Set printout parameters printout->SetDC(dc); int w, h; dc->GetSize(&w, &h); printout->SetPageSizePixels((int)w, (int)h); printout->SetPaperRectPixels(dc->GetPaperRect()); dc->GetSizeMM(&w, &h); printout->SetPageSizeMM((int)w, (int)h); // Create an abort window wxBusyCursor busyCursor; printout->OnPreparePrinting(); // Get some parameters from the printout, if defined int fromPage, toPage; int minPage, maxPage; printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage); if (maxPage == 0) { sm_lastError = wxPRINTER_ERROR; return false; } // Only set min and max, because from and to have been // set by the user m_printDialogData.SetMinPage(minPage); m_printDialogData.SetMaxPage(maxPage); wxWindow *win = CreateAbortWindow(parent, printout); wxYield(); #if defined(__WATCOMC__) || defined(__BORLANDC__) || defined(__GNUWIN32__) || defined(__SALFORDC__) || !defined(__WIN32__) #ifdef STRICT ::SetAbortProc((HDC) dc->GetHDC(), (ABORTPROC) m_lpAbortProc); #else ::SetAbortProc((HDC) dc->GetHDC(), (FARPROC) m_lpAbortProc); #endif #else ::SetAbortProc((HDC) dc->GetHDC(), (int (_stdcall *) // cast it to right type only if required // FIXME it's really cdecl and we're casting it to stdcall - either there is // something I don't understand or it will crash at first usage #ifdef STRICT (HDC, int) #else () #endif )m_lpAbortProc); #endif if (!win) { wxLogDebug(wxT("Could not create an abort dialog.")); sm_lastError = wxPRINTER_ERROR; delete dc; return false; } sm_abortWindow = win; sm_abortWindow->Show(); wxSafeYield(); printout->OnBeginPrinting(); sm_lastError = wxPRINTER_NO_ERROR; int minPageNum = minPage, maxPageNum = maxPage; if ( !m_printDialogData.GetAllPages() ) { minPageNum = m_printDialogData.GetFromPage(); maxPageNum = m_printDialogData.GetToPage(); } int copyCount; for ( copyCount = 1; copyCount <= m_printDialogData.GetNoCopies(); copyCount++ ) { if ( !printout->OnBeginDocument(minPageNum, maxPageNum) ) { wxLogError(_("Could not start printing.")); sm_lastError = wxPRINTER_ERROR; break; } if (sm_abortIt) { sm_lastError = wxPRINTER_CANCELLED; break; } int pn; for ( pn = minPageNum; pn <= maxPageNum && printout->HasPage(pn); pn++ ) { if ( sm_abortIt ) { sm_lastError = wxPRINTER_CANCELLED; break; } dc->StartPage(); bool cont = printout->OnPrintPage(pn); dc->EndPage(); if ( !cont ) { sm_lastError = wxPRINTER_CANCELLED; break; } } printout->OnEndDocument(); } printout->OnEndPrinting(); if (sm_abortWindow) { sm_abortWindow->Show(false); delete sm_abortWindow; sm_abortWindow = NULL; } delete dc; return sm_lastError == wxPRINTER_NO_ERROR; }
wxHtmlTag::wxHtmlTag(wxHtmlTag *parent, const wxString *source, const wxString::const_iterator& pos, const wxString::const_iterator& end_pos, wxHtmlTagsCache *cache, wxHtmlEntitiesParser *entParser) { /* Setup DOM relations */ m_Next = NULL; m_FirstChild = m_LastChild = NULL; m_Parent = parent; if (parent) { m_Prev = m_Parent->m_LastChild; if (m_Prev == NULL) m_Parent->m_FirstChild = this; else m_Prev->m_Next = this; m_Parent->m_LastChild = this; } else m_Prev = NULL; /* Find parameters and their values: */ wxChar c wxDUMMY_INITIALIZE(0); // fill-in name, params and begin pos: wxString::const_iterator i(pos+1); // find tag's name and convert it to uppercase: while ((i < end_pos) && ((c = *(i++)) != wxT(' ') && c != wxT('\r') && c != wxT('\n') && c != wxT('\t') && c != wxT('>') && c != wxT('/'))) { if ((c >= wxT('a')) && (c <= wxT('z'))) c -= (wxT('a') - wxT('A')); m_Name << c; } // if the tag has parameters, read them and "normalize" them, // i.e. convert to uppercase, replace whitespaces by spaces and // remove whitespaces around '=': if (*(i-1) != wxT('>')) { #define IS_WHITE(c) (c == wxT(' ') || c == wxT('\r') || \ c == wxT('\n') || c == wxT('\t')) wxString pname, pvalue; wxChar quote; enum { ST_BEFORE_NAME = 1, ST_NAME, ST_BEFORE_EQ, ST_BEFORE_VALUE, ST_VALUE } state; quote = 0; state = ST_BEFORE_NAME; while (i < end_pos) { c = *(i++); if (c == wxT('>') && !(state == ST_VALUE && quote != 0)) { if (state == ST_BEFORE_EQ || state == ST_NAME) { m_ParamNames.Add(pname); m_ParamValues.Add(wxGetEmptyString()); } else if (state == ST_VALUE && quote == 0) { m_ParamNames.Add(pname); if (entParser) m_ParamValues.Add(entParser->Parse(pvalue)); else m_ParamValues.Add(pvalue); } break; } switch (state) { case ST_BEFORE_NAME: if (!IS_WHITE(c)) { pname = c; state = ST_NAME; } break; case ST_NAME: if (IS_WHITE(c)) state = ST_BEFORE_EQ; else if (c == wxT('=')) state = ST_BEFORE_VALUE; else pname << c; break; case ST_BEFORE_EQ: if (c == wxT('=')) state = ST_BEFORE_VALUE; else if (!IS_WHITE(c)) { m_ParamNames.Add(pname); m_ParamValues.Add(wxGetEmptyString()); pname = c; state = ST_NAME; } break; case ST_BEFORE_VALUE: if (!IS_WHITE(c)) { if (c == wxT('"') || c == wxT('\'')) quote = c, pvalue = wxGetEmptyString(); else quote = 0, pvalue = c; state = ST_VALUE; } break; case ST_VALUE: if ((quote != 0 && c == quote) || (quote == 0 && IS_WHITE(c))) { m_ParamNames.Add(pname); if (quote == 0) { // VS: backward compatibility, no real reason, // but wxHTML code relies on this... :( pvalue.MakeUpper(); } if (entParser) m_ParamValues.Add(entParser->Parse(pvalue)); else m_ParamValues.Add(pvalue); state = ST_BEFORE_NAME; } else pvalue << c; break; } } #undef IS_WHITE } m_Begin = i; cache->QueryTag(pos, source->end(), &m_End1, &m_End2, &m_hasEnding); if (m_End1 > end_pos) m_End1 = end_pos; if (m_End2 > end_pos) m_End2 = end_pos; #if WXWIN_COMPATIBILITY_2_8 m_sourceStart = source->begin(); #endif }