目前我正試圖測驗IAutoComplete COM介面,這需要我使用MSVC cpp編譯器。我遇到了一個我在MingGW中從未遇到過的問題。MSVC看到我的throw陳述句,卻完全忽略了它。所以我不知道是否有什么設定是我沒有設定的。
好吧,我得到了一張反對票,這可能是我應得的,因為我舉了一個糟糕的例子。我認為它沒有被拋出是因為它在一個結構中,但用一個新的結構嘗試后證明我錯了。我可能無法提供一個可重復的例子,但我會盡力。
請準備好大量的代碼。
Jav/AutoObject.h
#ifndef JAV_WIN32_AUTO_OBJECT_HPP
#define JAV_WIN32_AUTO_OBJECT_HPP
#include <Jav/config.h>/span>
namespace Jav
{
struct AutoObject
{
virtual ~AutoObject(){}。
void* operator new(size_t sz)。
};
AutoObject* shallowCopy(AutoObject*)。
AutoObject* deleteObject(AutoObject*);
}
#endif //JAV_WIN32_AUTO_OBJECT_HPP
Jav/win32/widgets/widgets_ex.h
#ifndef JAV_WIN32_GUI_WIDGETS_EX_HPP
#define JAV_WIN32_GUI_WIDGETS_EX_HPP
#include <Jav/win32/widgets/widgets.h>
namespace Jav { namespace win32 {
classWidget
{
public:
Widget(HWND widget=nullptr) : widget(widget){}。
operator HWND(){ return widget; }
public:
void setId(int id) { SetWindowLong(widget, GWLP_ID,id)。}
void destroy() { DestroyWindow(widget)。widget = NULL; }
void show() { ShowWindow(widget,SW_SHOW); }
void hide() { ShowWindow(widget, SW_HIDE); }
protected:
HWND widget。
};
}}
#endif // JAV_WIN32_GUI_WIDGETS_EX_HPP
Jav/win32/window/Window.h
#include <Jav/win32/widgets/widgets_ex.h>
using Window = Widget;
Jav/win32/window/SimpleWindow.h
#ifndef JAV_WIN32_WINDOW_SIMPLE_WINDOW_HPP
#define JAV_WIN32_WINDOW_SIMPLE_WINDOW_HPP
#include <Jav/AutoObject.h>/span>
#include <Jav/win32/window/Window.h>/span>
namespace Jav { namespace win32 {
struct Content__ : AutoObject
{
virtual void onCreate(HWND,CREATESTRUCTA*){}。
virtual void onDestroy() {}
virtual void onSize(int w。 int h){}。
virtual void onDraw(Canvas&) {}。
};
class SimpleWindow : public Window
{
public:
SimpleWindow(Content__*, const char *title, size_t w,size_t h,
int style=WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
int ex_style=0)。)
public:
bool isOpen()。
void close;
const MSG& getMessage();
const MSG& peekMessage()。
void dispatchMessage(const MSG& )。
private:
static ATOM registerWindow()。
static LRESULT CALLBACK windowProc(HWND,UINT,WPARAM,LPARAM)。
static HWND createWindow(Content__*, const char *, HMENU, size_t,size_t, int,int)。
private:
MSG味精。
};
}}
#endif //JAV_WIN32_WINDOW_SIMPLE_WINDOW_HPP
AutoObject.cpp
#include <Jav/AutoObject.h>/span>
#include <unordered_map>/span>
#include <objbase.h>
namespace {
struct AutoObjectsMap : std::unordered_map<Jav::AutoObject*, size_t>
{
~AutoObjectsMap() { for(auto & obj : *this) CoTaskMemFree(obj.first); };CoTaskMemFree?
};
AutoObjectsMap *alloc_objects_ptr;
struct AutoObjectsMapMgr
{
~AutoObjectsMapMgr() { delete alloc_objects_ptr; };
};
}
#define alloc_objects (*alloc_objects_ptr)
namespace Jav
{
void* AutoObject::operator new(size_t sz)
{
auto mem = CoTaskMemAlloc(sz)。
if(!alloc_objects_ptr) alloc_objects_ptr = new AutoObjectsMap() 。
alloc_objects[(AutoObject*)mem] = 1;
return mem。
}
AutoObject* shallowCopy(AutoObject *r)
{
auto elem = alloc_objects.find(r)。
if( elem != alloc_objects.end() ) alloc_objects[r];
return r;
}
AutoObject* deleteObject(AutoObject *mem)
{
auto elem = alloc_objects.find(mem)。
if( elem != alloc_objects.end() )
{
if(--elem-> second == 0)
{
mem->~AutoObject()。
CoTaskMemFree(mem)。
alloc_objects.erase(elem)。
return nullptr。
}
}
return mem;
}
SimpleWindow.cpp
#include <Jav/win32/window/SimpleWindow.h>/span>
namespace Jav { namespace win32 {
namespace {
LRESULT CALLBACK SimpleWindow::windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
Content__ *obj = (Content__*)GetWindowLongPtrA(hwnd,GWLP_USERDATA)。
auto getWidth = [lParam](){ return LOWORD(lParam); };
auto getHeight = [lParam](){ return HIWORD(lParam); };
auto getX = [lParam](){ return LOWORD(lParam); };
auto getY = [lParam](){ return HIWORD(lParam); };
auto getWidget = [lParam](){ return (HWND)lParam; };
auto widgetId = [wParam](){ return LOWORD(wParam); };
auto widgetEvent = [wParam](){ return HIWORD(wParam); };
auto menuType = [wParam](){ return LOWORD(wParam); };
auto eventId = [wParam](){ return LOWORD(wParam); };
switch (uMsg)
{
case WM_CREATE:
{
CREATESTRUCT *cs = ((CREATESTRUCTA*)lParam);
obj = (Content__*)cs->lpCreateParams;
SetWindowLongPtr(hwnd,GWLP_USERDATA, (LONG_PTR)obj);
obj->onCreate(hwnd,cs)。
return 0;
}
case WM_DESTROY:
obj->onDestroy();
deleteObject(obj)。
return 0;
case WM_SIZE:
obj->onSize(getWidth(),getHeight() 。)
return 0;
default: return DefWindowProc(hwnd, uMsg, wParam, lParam)。
}
}
ATOM SimpleWindow::registerWindow()
{
WNDCLASSEX wincl = {};
wincl.cbSize = sizeof(WNDCLASSEX)。
wincl.lpszClassName = "JavWin32WindowSimpleWindow"/span>;
wincl.lpfnWndProc = SimpleWindow::windowProc;
wincl.style = CS_HREDRAW|CS_VREDRAW;
wincl.hIcon = LoadIcon(NULL,IDI_APPLICATION); 。
wincl.hIconSm = LoadIcon(NULL,IDI_APPLICATION)。
wincl.hCursor = LoadCursor(NULL, IDC_ARROW);
wincl.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wincl.cbWndExtra = WINDOW_WND_EXTRA_BYTES;
return RegisterClassEx(&wincl)。
}
SimpleWindow:: SimpleWindow(Content__ *obj,const char *title, size_t w,size_t h, int style,int ex_style)
: Window( createWindow(obj,title,NULL, w,h, style,ex_style) ) 。
app_ctx(*this)
{
msg.message = 0;
show()。
}
bool SimpleWindow::isOpen()
{
return msg.message != WM_QUIT;
}
void SimpleWindow::close()
{
DestroyWindow(*this)。
}
const MSG& SimpleWindow::getMessage()
{
GetMessageA(&msg,*this,0, 0)。
return msg;
}
const MSG& SimpleWindow::peekMessage()
{
PeekMessageA(&msg,*this,0,0, PM_REMOVE)。
return msg;
}
void SimpleWindow::dispatchMessage(const MSG &msg)
{
TranslateMessage(&msg)。
DispatchMessage(&msg)。
}
}}
main.cpp
#include <Jav/AutoObject.h>
#include <Jav/win32/window/SimpleWindow.h>/span>
using namespace Jav::win32;
class Content : public Content__。
{
IAutoComplete *pac = NULL。
IAutoComplete2 *pac2 = NULL;
//IUnknown *punkSource;/span>
//ColumnList columnList;
public:
~Content()
{
if(pac) pac->Release()。
if(pac2) pac2->Release()。
}
void onCreate(HWND hwnd,CREATESTRUCTA*)override
{
throw; //doesn't throw or terminate。
HWND textBox; //假裝這是一個編輯控制元件。
attachAutoCompleteObject(textBox); //不會拋出
}
void attachAutoCompleteObject(HWND hwnd)
{
HRESULT hr = CoCreateInstance(CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&amp; pac))。
if(FAILED(hr)) throw "Failed to create AutoComplete Object
"。
hr = pac->Init(hwnd, &columnList, NULL, NULL)。
if(FAILED(hr)) throw "Failed to attach auto complete object
"。
hr = pac->QueryInterface(IID_PPV_ARGS(&pac2)); rep(pac2)。
if (FAILED(hr)) throw "Failed to set autocomplete options
"。
hr = pac2->SetOptions(ACO_AUTOSUGGEST)。
}
};
int main()
{
內容的內容。
SimpleWindow win(& content,"",640,480)。
while(win.isOpen()
{
auto &msg = win.getMessage()。
win.dispatchMessage(msg)。
}
uj5u.com熱心網友回復:
throw;單獨做的不是你認為的那樣。事實上,不清楚你期望發生什么。從cppreference:
throw expression (1)
拋出 (2)
- [...]
當當前沒有期望被處理時,那么
- 拋出當前處理的例外。放棄當前catch塊的執行,并將控制權傳遞給下一個匹配的例外處理程式(但不能傳遞給同一try塊后的另一個catch子句:其復合陳述句被認為已經 "退出"),重新使用現有的例外物件:不產生新的物件。這種形式只允許在目前正在處理例外的情況下使用(如果不這樣使用,就會呼叫std::terminate)。如果在建構式上使用,與函式-嘗試塊相關的 catch 子句必須通過重新拋出退出。
throw;單獨是錯誤的。它直接終止了程式。如果你想拋出一個例外,可以嘗試這樣做。
throw 42;
throw; //this also throws;/span>
不,這不應該拋出。它應該呼叫std::terminate。
uj5u.com熱心網友回復:
所以你似乎有throw "literal"而不是你最初發布的throw;。那么它確實應該拋出。這里的問題是,你試圖拋出通過Windows DLLs的例外,像GetMessage/DispatchMessage結構或COM方法調度,這是不保證作業的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/333051.html
標籤:
